Skip to content

Commit

Permalink
Merge pull request #160 from wentout/proto
Browse files Browse the repository at this point in the history
decorators
  • Loading branch information
wentout committed Nov 12, 2023
2 parents fc543a4 + b26b53d commit fe43e77
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 25 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
test/example.js
test/decorate.js
build/**/*.d.ts
.eslintrc.js
2 changes: 2 additions & 0 deletions build/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export declare const lookup: TypeLookup;
export declare const apply: <E extends object, T extends object, S extends Proto<E, T>>(entity: E, Constructor: IDEF<T>, args?: unknown[]) => { [key in keyof S]: S[key]; };
export declare const call: <E extends object, T extends object, S extends Proto<E, T>>(entity: E, Constructor: IDEF<T>, ...args: unknown[]) => { [key in keyof S]: S[key]; };
export declare const bind: <E extends object, T extends object, S extends Proto<E, T>>(entity: E, Constructor: IDEF<T>) => (...args: unknown[]) => { [key in keyof S]: S[key]; };
export declare const decorate: (parentClass?: unknown, proto?: object, config?: constructorOptions) => <T extends new () => unknown>(cstr: T, s: ClassDecoratorContext<T>) => T;
export declare const registerHook: <T extends object>(Constructor: IDEF<T>, hookType: hooksTypes, cb: hook) => void;
export declare const mnemonica: {
[index: string]: unknown;
};
Expand Down
20 changes: 18 additions & 2 deletions build/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.defineStackCleaner = exports.utils = exports.errors = exports.defaultCollection = exports.createTypesCollection = exports.defaultNamespace = exports.namespaces = exports.createNamespace = exports.ErrorMessages = exports.TYPE_TITLE_PREFIX = exports.URANUS = exports.GAIA = exports.MNEMOSYNE = exports.MNEMONICA = exports.SymbolConfig = exports.SymbolDefaultTypesCollection = exports.SymbolDefaultNamespace = exports.SymbolReplaceGaia = exports.SymbolGaia = exports.SymbolConstructorName = exports.SymbolSubtypeCollection = exports.mnemonica = exports.bind = exports.call = exports.apply = exports.lookup = exports.define = exports.defaultTypes = void 0;
exports.defineStackCleaner = exports.utils = exports.errors = exports.defaultCollection = exports.createTypesCollection = exports.defaultNamespace = exports.namespaces = exports.createNamespace = exports.ErrorMessages = exports.TYPE_TITLE_PREFIX = exports.URANUS = exports.GAIA = exports.MNEMOSYNE = exports.MNEMONICA = exports.SymbolConfig = exports.SymbolDefaultTypesCollection = exports.SymbolDefaultNamespace = exports.SymbolReplaceGaia = exports.SymbolGaia = exports.SymbolConstructorName = exports.SymbolSubtypeCollection = exports.mnemonica = exports.registerHook = exports.decorate = exports.bind = exports.call = exports.apply = exports.lookup = exports.define = exports.defaultTypes = void 0;
const constants_1 = require("./constants");
const { odp } = constants_1.constants;
const errorsApi = require("./api/errors");
Expand Down Expand Up @@ -35,11 +35,27 @@ const bind = function (entity, Constructor) {
};
};
exports.bind = bind;
const decorate = function (parentClass = undefined, proto, config) {
const decorator = function (cstr, s) {
if (parentClass === undefined) {
return (0, exports.define)(s.name, cstr, proto, config);
}
return parentClass.define(s.name, cstr, proto, config);
};
return decorator;
};
exports.decorate = decorate;
const registerHook = function (Constructor, hookType, cb) {
Constructor.registerHook(hookType, cb);
};
exports.registerHook = registerHook;
exports.mnemonica = Object.entries(Object.assign(Object.assign(Object.assign({ define: exports.define,
lookup: exports.lookup,
apply: exports.apply,
call: exports.call,
bind: exports.bind }, descriptors_1.descriptors), errorsApi), constants_1.constants)).reduce((acc, entry) => {
bind: exports.bind,
decorate: exports.decorate,
registerHook: exports.registerHook }, descriptors_1.descriptors), errorsApi), constants_1.constants)).reduce((acc, entry) => {
const [name, code] = entry;
odp(acc, name, {
get() {
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mnemonica",
"version": "0.9.978",
"version": "0.9.98",
"description": "abstract technique that aids information retention : instance inheritance system",
"type": "commonjs",
"main": "./build/index.js",
Expand Down
39 changes: 21 additions & 18 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* eslint-disable new-cap */
/* eslint-disable @typescript-eslint/ban-ts-comment, indent, new-cap, space-before-function-paren */
'use strict';

import { TypeLookup, IDEF } from './types';
Expand Down Expand Up @@ -113,16 +113,6 @@ export const define = function <
config?: constructorOptions,
): R {
const types = checkThis(this) ? defaultTypes : this || defaultTypes;
// if (typeof constructHandler !== 'function') {
// // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// // @ts-ignore
// // eslint-disable-next-line @typescript-eslint/ban-types, @typescript-eslint/no-unused-vars
// return function (decoratorConstructHandler: Function, y: unknown) {
// if (typeof decoratorConstructHandler === 'function') {
// types.define(decoratorConstructHandler.name, decoratorConstructHandler, proto, config);
// }
// };
// }
return types.define(TypeName, constructHandler, proto, config);
};

Expand All @@ -134,8 +124,6 @@ export const lookup = function (TypeNestedPath) {
export const apply = function <E extends object, T extends object, S extends Proto<E, T>> (entity: E, Constructor: IDEF<T>, args: unknown[] = []): {
[key in keyof S]: S[key]
} {
// const result = Constructor.apply(entity, args);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const result = new entity[ Constructor.TypeName ](...args);
return result;
Expand All @@ -144,9 +132,7 @@ export const apply = function <E extends object, T extends object, S extends Pro
export const call = function <E extends object, T extends object, S extends Proto<E, T>> (entity: E, Constructor: IDEF<T>, ...args: unknown[]): {
[key in keyof S]: S[key]
} {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// const result = Constructor.call(entity, ...args);
const result = new entity[ Constructor.TypeName ](...args);
return result;
};
Expand All @@ -155,20 +141,37 @@ export const bind = function <E extends object, T extends object, S extends Prot
[key in keyof S]: S[key]
} {
return (...args) => {
// const result = Constructor.call(entity, ...args);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const result = new entity[ Constructor.TypeName ](...args);
return result;
};
};

export const decorate = function (parentClass: unknown = undefined, proto?: object, config?: constructorOptions ) {
const decorator = function<T extends { new(): unknown }>(cstr: T, s: ClassDecoratorContext<T>): T {
if (parentClass === undefined ) {
return define(s.name, cstr, proto, config) as unknown as typeof cstr;
}
// @ts-ignore
return parentClass.define(s.name, cstr, proto, config) as unknown as typeof cstr;
};
return decorator;
};

export const registerHook = function <T extends object> (Constructor: IDEF<T>, hookType: hooksTypes, cb: hook): void {
// @ts-ignore
Constructor.registerHook(hookType, cb);
};

export const mnemonica = Object.entries({

define,
lookup,
apply,
call,
bind,
decorate,
registerHook,

...descriptors,

Expand Down Expand Up @@ -214,4 +217,4 @@ export const errors = descriptors.ErrorsTypes;

export { utils } from './utils';
export { defineStackCleaner } from './utils';
/* eslint-enable new-cap */
/* eslint-enable @typescript-eslint/ban-ts-comment, indent, new-cap, space-before-function-paren */
88 changes: 88 additions & 0 deletions test/decorate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
"use strict";
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
var _, done = false;
for (var i = decorators.length - 1; i >= 0; i--) {
var context = {};
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
if (kind === "accessor") {
if (result === void 0) continue;
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
if (_ = accept(result.get)) descriptor.get = _;
if (_ = accept(result.set)) descriptor.set = _;
if (_ = accept(result.init)) initializers.unshift(_);
}
else if (_ = accept(result)) {
if (kind === "field") initializers.unshift(_);
else descriptor[key] = _;
}
}
if (target) Object.defineProperty(target, contextIn.name, descriptor);
done = true;
};
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
var useValue = arguments.length > 2;
for (var i = 0; i < initializers.length; i++) {
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
}
return useValue ? value : void 0;
};
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.myDecoratedSubInstance = exports.myDecoratedInstance = void 0;
var __1 = require("..");
debugger;
var MyDecoratedClass = function () {
var _classDecorators = [(0, __1.decorate)(undefined, {}, { strictChain: false })];
var _classDescriptor;
var _classExtraInitializers = [];
var _classThis;
var MyDecoratedClass = _classThis = /** @class */ (function () {
function MyDecoratedClass_1() {
this.field = 123;
}
return MyDecoratedClass_1;
}());
__setFunctionName(_classThis, "MyDecoratedClass");
(function () {
var _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
MyDecoratedClass = _classThis = _classDescriptor.value;
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
__runInitializers(_classThis, _classExtraInitializers);
})();
return MyDecoratedClass = _classThis;
}();
debugger;
var MyDecoratedSubClass = function () {
var _classDecorators = [(0, __1.decorate)(MyDecoratedClass)];
var _classDescriptor;
var _classExtraInitializers = [];
var _classThis;
var MyDecoratedSubClass = _classThis = /** @class */ (function () {
function MyDecoratedSubClass_1() {
this.sub_field = 321;
}
return MyDecoratedSubClass_1;
}());
__setFunctionName(_classThis, "MyDecoratedSubClass");
(function () {
var _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
MyDecoratedSubClass = _classThis = _classDescriptor.value;
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
__runInitializers(_classThis, _classExtraInitializers);
})();
return MyDecoratedSubClass = _classThis;
}();
exports.myDecoratedInstance = new MyDecoratedClass;
exports.myDecoratedSubInstance = (0, __1.apply)(exports.myDecoratedInstance, MyDecoratedSubClass);
23 changes: 23 additions & 0 deletions test/decorate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { decorate, apply }from '..';


debugger;
@decorate(undefined, {}, { strictChain : false })
class MyDecoratedClass {
field: number;
constructor () {
this.field = 123;
}
}

debugger;
@decorate(MyDecoratedClass)
class MyDecoratedSubClass {
sub_field: number;
constructor () {
this.sub_field = 321;
}
}

export const myDecoratedInstance = new MyDecoratedClass;
export const myDecoratedSubInstance = apply(myDecoratedInstance, MyDecoratedSubClass);
9 changes: 9 additions & 0 deletions test/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const tests = (opts) => {
subOfSomeADTCInstanceANoArgs,
subOfSomeADTCInstanceC,
subOfSomeADTCInstanceB,
myDecoratedSubInstance,
anotherNamespace,
anotherTypesCollection,
oneElseTypesCollection,
Expand Down Expand Up @@ -103,6 +104,9 @@ const tests = (opts) => {
'apply',
'call',
'bind',
'decorate',
'registerHook',

];

const mnemonica_keys = Object.keys(mnemonica);
Expand Down Expand Up @@ -349,6 +353,11 @@ const tests = (opts) => {
expect(someADTCInstance.test).equal(123);
});

it('decorate works correctly', () => {
expect(myDecoratedSubInstance.sub_field).equal(321);
expect(myDecoratedSubInstance.field).equal(123);
});

it('apply & call works correctly', () => {

expect(SubOfSomeADTCTypePre.existentInstance).equal(someADTCInstance);
Expand Down
8 changes: 5 additions & 3 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@ const asyncConstructionTest = true;

const mnemonica = require('..');

const { myDecoratedSubInstance } = require('./decorate');

const {
define,
apply,
call,
bind,
registerHook,
defaultTypes: types,
createNamespace,
createTypesCollection,
Expand Down Expand Up @@ -67,7 +70,7 @@ const UserType = mnemonica.define('UserType', function (userData) {

const userTypeHooksInvocations = [];

UserType.registerHook('preCreation', function (opts) {
registerHook(UserType, 'preCreation', function (opts) {
userTypeHooksInvocations.push({
kind : 'pre',
sort : 'type',
Expand Down Expand Up @@ -387,8 +390,6 @@ SubOfNestedAsync.registerHook('postCreation', function (opts) {
SubOfNestedAsyncPostHookData = opts;
});



// debugger;
describe('Main Test', () => {

Expand Down Expand Up @@ -618,6 +619,7 @@ describe('Main Test', () => {
backSub,
subOfSomeADTCInstanceC,
subOfSomeADTCInstanceB,
myDecoratedSubInstance,
anotherNamespace,
anotherTypesCollection,
oneElseTypesCollection,
Expand Down

0 comments on commit fe43e77

Please sign in to comment.