@arkstack/common 0.12.16 → 0.12.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/utils/index.d.ts +29 -2
- package/dist/utils/index.js +2 -2
- package/dist/{utils-CMuDt6cA.js → utils-Y1a3rhA3.js} +103 -22
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { C as importFile, E as outputDir, S as env, T as nodeEnv, _ as Hash, b as appUrl, c as abortIf, d as initializeGlobalContext, f as isClass, g as Exception, h as AppException, l as assertFound, m as RequestException, p as perPage, s as abort, u as getModel, v as Encryption, w as interopDefault, x as config, y as CONFIG_KEY } from "./utils-Y1a3rhA3.js";
|
|
2
2
|
import { Hook as Hook$1 } from "@arkstack/foundry";
|
|
3
3
|
import { str } from "@h3ravel/support";
|
|
4
4
|
import { Arkstack } from "@arkstack/contract";
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -134,13 +134,40 @@ type DeriveTraitsStats<T extends ((Trait | TypeFactory<Trait>)[] | [...(Trait |
|
|
|
134
134
|
* utility type: derive type from one or more traits or trait type factories
|
|
135
135
|
*/
|
|
136
136
|
type DeriveTraits<T extends ((Trait | TypeFactory<Trait>)[] | [...(Trait | TypeFactory<Trait>)[], DirectBase])> = DeriveTraitsCons<T> & DeriveTraitsStats<T>;
|
|
137
|
+
type TraitMethodHelpers = {
|
|
138
|
+
getTraitMethods: <T extends TraitMethod = TraitMethod>(name: PropertyKey) => T[];
|
|
139
|
+
callTraitMethods: <T = any>(name: PropertyKey, ...args: any[]) => T[];
|
|
140
|
+
};
|
|
141
|
+
type DeriveTraitsWithMethodHelpers<T extends ((Trait | TypeFactory<Trait>)[] | [...(Trait | TypeFactory<Trait>)[], DirectBase])> = DeriveTraits<T> extends (new (...args: infer Args) => infer Instance) ? (new (...args: Args) => Instance & TraitMethodHelpers) & Omit<DeriveTraits<T>, 'prototype'> & TraitMethodHelpers : never;
|
|
142
|
+
type TraitMethod = (...args: any[]) => any;
|
|
143
|
+
/**
|
|
144
|
+
* Return every trait implementation for a method, bound to the supplied
|
|
145
|
+
* instance or class. Methods are ordered from the base implementation to the
|
|
146
|
+
* currently active trait implementation.
|
|
147
|
+
*
|
|
148
|
+
* @param target
|
|
149
|
+
* @param name
|
|
150
|
+
* @returns
|
|
151
|
+
*/
|
|
152
|
+
declare const getTraitMethods: <T extends TraitMethod = TraitMethod>(target: object | Cons, name: PropertyKey) => T[];
|
|
153
|
+
/**
|
|
154
|
+
* Invoke every trait implementation for a method in registration order.
|
|
155
|
+
*
|
|
156
|
+
* @param target
|
|
157
|
+
* @param name
|
|
158
|
+
* @param args
|
|
159
|
+
* @returns
|
|
160
|
+
*/
|
|
161
|
+
declare const callTraitMethods: <T = any>(target: object | Cons, name: PropertyKey, ...args: any[]) => T[];
|
|
162
|
+
type UsableTraits = ([Trait | TypeFactory<Trait>, ...(Trait | TypeFactory<Trait>)[]] | [...(Trait | TypeFactory<Trait>)[], DirectBase]);
|
|
137
163
|
/**
|
|
138
164
|
* API: derive a class from one or more traits or trait type factories
|
|
139
165
|
*
|
|
140
166
|
* @param traits
|
|
141
167
|
* @returns
|
|
142
168
|
*/
|
|
143
|
-
declare function use<T extends
|
|
169
|
+
declare function use<T extends UsableTraits>(withMethodHelpers: true, ...traits: T): DeriveTraitsWithMethodHelpers<T>;
|
|
170
|
+
declare function use<T extends UsableTraits>(...traits: T): DeriveTraits<T>;
|
|
144
171
|
/**
|
|
145
172
|
* internal type: implements trait type
|
|
146
173
|
*/
|
|
@@ -158,4 +185,4 @@ type Derived<T extends (Trait | TypeFactory<Trait> | Cons)> = T extends TypeFact
|
|
|
158
185
|
*/
|
|
159
186
|
declare function uses<T extends (Trait | TypeFactory<Trait> | Cons)>(instance: unknown, trait: T): instance is Derived<T>;
|
|
160
187
|
//#endregion
|
|
161
|
-
export { AbstractModelConstructor, Derived, Encryption, Hash, ModelConstructor, ModelRegistry, Trait, abort, abortIf, assertFound, crc32, getModel, initializeGlobalContext, isClass, perPage, trait, use, uses };
|
|
188
|
+
export { AbstractModelConstructor, Derived, Encryption, Hash, ModelConstructor, ModelRegistry, Trait, abort, abortIf, assertFound, callTraitMethods, crc32, getModel, getTraitMethods, initializeGlobalContext, isClass, perPage, trait, use, uses };
|
package/dist/utils/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { Encryption, Hash, abort, abortIf, assertFound, crc32, getModel, initializeGlobalContext, isClass, perPage, trait, use, uses };
|
|
1
|
+
import { _ as Hash, a as use, c as abortIf, d as initializeGlobalContext, f as isClass, i as trait, l as assertFound, n as crc32, o as uses, p as perPage, r as getTraitMethods, s as abort, t as callTraitMethods, u as getModel, v as Encryption } from "../utils-Y1a3rhA3.js";
|
|
2
|
+
export { Encryption, Hash, abort, abortIf, assertFound, callTraitMethods, crc32, getModel, getTraitMethods, initializeGlobalContext, isClass, perPage, trait, use, uses };
|
|
@@ -418,6 +418,75 @@ const extendProperties = (cons, field, value) => Object.defineProperty(cons, fie
|
|
|
418
418
|
enumerable: false,
|
|
419
419
|
writable: false
|
|
420
420
|
});
|
|
421
|
+
const traitMethodRegistry = Symbol("trait-method-registry");
|
|
422
|
+
const cloneMethodRegistry = (target) => {
|
|
423
|
+
const registry = target[traitMethodRegistry];
|
|
424
|
+
return new Map([...registry?.entries() ?? []].map(([name, methods]) => [name, [...methods]]));
|
|
425
|
+
};
|
|
426
|
+
const registerMethodScope = (target, base, ignored) => {
|
|
427
|
+
const registry = cloneMethodRegistry(base);
|
|
428
|
+
for (const name of Reflect.ownKeys(target)) {
|
|
429
|
+
if (ignored.has(name)) continue;
|
|
430
|
+
const method = Object.getOwnPropertyDescriptor(target, name)?.value;
|
|
431
|
+
if (typeof method !== "function") continue;
|
|
432
|
+
const methods = registry.get(name);
|
|
433
|
+
const previous = base?.[name];
|
|
434
|
+
if (methods) {
|
|
435
|
+
if (methods.at(-1) !== method) methods.push(method);
|
|
436
|
+
registry.set(name, methods);
|
|
437
|
+
} else if (typeof previous === "function" && previous !== method) registry.set(name, [previous, method]);
|
|
438
|
+
}
|
|
439
|
+
Object.defineProperty(target, traitMethodRegistry, {
|
|
440
|
+
configurable: false,
|
|
441
|
+
enumerable: false,
|
|
442
|
+
value: registry,
|
|
443
|
+
writable: false
|
|
444
|
+
});
|
|
445
|
+
};
|
|
446
|
+
/**
|
|
447
|
+
* Registers conflicting trait methods
|
|
448
|
+
*
|
|
449
|
+
* @param classInstance
|
|
450
|
+
* @param baseClass
|
|
451
|
+
*/
|
|
452
|
+
const registerTraitMethods = (classInstance, baseClass) => {
|
|
453
|
+
registerMethodScope(classInstance.prototype, baseClass.prototype, new Set(["constructor"]));
|
|
454
|
+
registerMethodScope(classInstance, baseClass, new Set([
|
|
455
|
+
"length",
|
|
456
|
+
"name",
|
|
457
|
+
"prototype",
|
|
458
|
+
"arguments",
|
|
459
|
+
"caller"
|
|
460
|
+
]));
|
|
461
|
+
};
|
|
462
|
+
/**
|
|
463
|
+
* Return every trait implementation for a method, bound to the supplied
|
|
464
|
+
* instance or class. Methods are ordered from the base implementation to the
|
|
465
|
+
* currently active trait implementation.
|
|
466
|
+
*
|
|
467
|
+
* @param target
|
|
468
|
+
* @param name
|
|
469
|
+
* @returns
|
|
470
|
+
*/
|
|
471
|
+
const getTraitMethods = (target, name) => {
|
|
472
|
+
return (((typeof target === "function" ? target : Object.getPrototypeOf(target))?.[traitMethodRegistry])?.get(name) ?? []).map((method) => method.bind(target));
|
|
473
|
+
};
|
|
474
|
+
/**
|
|
475
|
+
* Invoke every trait implementation for a method in registration order.
|
|
476
|
+
*
|
|
477
|
+
* @param target
|
|
478
|
+
* @param name
|
|
479
|
+
* @param args
|
|
480
|
+
* @returns
|
|
481
|
+
*/
|
|
482
|
+
const callTraitMethods = (target, name, ...args) => {
|
|
483
|
+
const methods = getTraitMethods(target, name);
|
|
484
|
+
if (methods.length === 0) {
|
|
485
|
+
console.warn(`No conflicting trait methods found for "${String(name)}".`);
|
|
486
|
+
return [];
|
|
487
|
+
}
|
|
488
|
+
return methods.map((method) => method(...args));
|
|
489
|
+
};
|
|
421
490
|
/**
|
|
422
491
|
* utility function: get raw trait
|
|
423
492
|
*
|
|
@@ -429,21 +498,23 @@ const rawTrait = (x) => isTypeFactory(x) ? x() : x;
|
|
|
429
498
|
* utility function: derive a trait
|
|
430
499
|
*
|
|
431
500
|
* @param trait$
|
|
432
|
-
* @param
|
|
501
|
+
* @param baseClass
|
|
433
502
|
* @param derived
|
|
434
503
|
* @returns
|
|
435
504
|
*/
|
|
436
|
-
const deriveTrait = (trait$,
|
|
505
|
+
const deriveTrait = (trait$, baseClass, derived) => {
|
|
437
506
|
const trait = rawTrait(trait$);
|
|
438
|
-
let
|
|
507
|
+
let classInstance = baseClass;
|
|
439
508
|
if (!derived.has(trait.id)) {
|
|
440
509
|
derived.set(trait.id, true);
|
|
441
|
-
if (trait.superTraits !== void 0) for (const superTrait of reverseTraitList(trait.superTraits))
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
510
|
+
if (trait.superTraits !== void 0) for (const superTrait of reverseTraitList(trait.superTraits)) classInstance = deriveTrait(superTrait, classInstance, derived);
|
|
511
|
+
const base = classInstance;
|
|
512
|
+
classInstance = trait.factory(classInstance);
|
|
513
|
+
registerTraitMethods(classInstance, base);
|
|
514
|
+
extendProperties(classInstance, "id", crc32(trait.factory.toString()));
|
|
515
|
+
extendProperties(classInstance, trait.symbol, true);
|
|
445
516
|
}
|
|
446
|
-
return
|
|
517
|
+
return classInstance;
|
|
447
518
|
};
|
|
448
519
|
/**
|
|
449
520
|
* utility function: get reversed trait list
|
|
@@ -452,30 +523,40 @@ const deriveTrait = (trait$, baseClz, derived) => {
|
|
|
452
523
|
* @returns
|
|
453
524
|
*/
|
|
454
525
|
const reverseTraitList = (traits) => traits.slice().reverse();
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
* @param traits
|
|
459
|
-
* @returns
|
|
460
|
-
*/
|
|
461
|
-
function use(...traits) {
|
|
526
|
+
function use(...args) {
|
|
527
|
+
const withMethodHelpers = args[0] === true;
|
|
528
|
+
const traits = withMethodHelpers ? args.slice(1) : args;
|
|
462
529
|
if (traits.length === 0) throw new Error("invalid number of parameters (expected one or more traits)");
|
|
463
|
-
let
|
|
530
|
+
let classInstance;
|
|
464
531
|
let lot;
|
|
465
532
|
const last = traits[traits.length - 1];
|
|
466
533
|
if (isCons(last) && !isTypeFactory(last)) {
|
|
467
|
-
|
|
534
|
+
classInstance = last;
|
|
468
535
|
lot = traits.slice(0, -1);
|
|
469
536
|
} else if (isArkormModelInstance(last)) {
|
|
470
|
-
|
|
537
|
+
classInstance = last.constructor;
|
|
471
538
|
lot = traits.slice(0, -1);
|
|
472
539
|
} else {
|
|
473
|
-
|
|
540
|
+
classInstance = class ROOT {};
|
|
474
541
|
lot = traits;
|
|
475
542
|
}
|
|
476
543
|
const derived = /* @__PURE__ */ new Map();
|
|
477
|
-
for (const trait of reverseTraitList(lot))
|
|
478
|
-
|
|
544
|
+
for (const trait of reverseTraitList(lot)) classInstance = deriveTrait(trait, classInstance, derived);
|
|
545
|
+
if (withMethodHelpers) classInstance = class TraitMethodEnabled extends classInstance {
|
|
546
|
+
getTraitMethods(name) {
|
|
547
|
+
return getTraitMethods(this, name);
|
|
548
|
+
}
|
|
549
|
+
callTraitMethods(name, ...args) {
|
|
550
|
+
return callTraitMethods(this, name, ...args);
|
|
551
|
+
}
|
|
552
|
+
static getTraitMethods(name) {
|
|
553
|
+
return getTraitMethods(this, name);
|
|
554
|
+
}
|
|
555
|
+
static callTraitMethods(name, ...args) {
|
|
556
|
+
return callTraitMethods(this, name, ...args);
|
|
557
|
+
}
|
|
558
|
+
};
|
|
559
|
+
return classInstance;
|
|
479
560
|
}
|
|
480
561
|
/**
|
|
481
562
|
* API: type guard for checking whether class instance is derived from a trait
|
|
@@ -498,4 +579,4 @@ function uses(instance, trait) {
|
|
|
498
579
|
return false;
|
|
499
580
|
}
|
|
500
581
|
//#endregion
|
|
501
|
-
export {
|
|
582
|
+
export { importFile as C, outputDir as E, env as S, nodeEnv as T, Hash as _, use as a, appUrl as b, abortIf as c, initializeGlobalContext as d, isClass as f, Exception as g, AppException as h, trait as i, assertFound as l, RequestException as m, crc32 as n, uses as o, perPage as p, getTraitMethods as r, abort as s, callTraitMethods as t, getModel as u, Encryption as v, interopDefault as w, config as x, CONFIG_KEY as y };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arkstack/common",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.18",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Core utilities, primitives, and shared infrastructure for the Arkstack ecosystem.",
|
|
6
6
|
"homepage": "https://arkstack.toneflix.net",
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"@h3ravel/support": "^0.15.11",
|
|
44
|
-
"arkormx": "^
|
|
45
|
-
"@arkstack/foundry": "^0.12.
|
|
46
|
-
"@arkstack/contract": "^0.12.
|
|
44
|
+
"arkormx": "^2.5.2",
|
|
45
|
+
"@arkstack/foundry": "^0.12.18",
|
|
46
|
+
"@arkstack/contract": "^0.12.18"
|
|
47
47
|
},
|
|
48
48
|
"scripts": {
|
|
49
49
|
"build": "tsdown --config-loader unrun",
|