adaptive-extender 0.10.3 → 0.10.4

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/CHANGELOG.md CHANGED
@@ -1,4 +1,4 @@
1
- ## 0.10.3 (05.06.2026)
1
+ ## 0.10.4 (13.06.2026)
2
2
  - Added `Function.empty` constant — a shared no-op function available via `Function.empty`.
3
3
  - Added [function](./src/core/function.ts) module to the core package.
4
4
  - Added [metadata-injector](./src/web/metadata-injector.ts) module to the web package. Provides `MetadataInjector.inject()` for one-shot injection of structured JSON-LD metadata, Open Graph meta tags, and `rel=me` links into the document head. Supports `Person`, `Application`, and `Organization` entity types.
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ Reflect.set(Symbol, "metadata", Reflect.get(Symbol, "metadata") ?? Symbol.for("Symbol.metadata"));
2
3
  globalThis.constructor = function (value) {
3
4
  return value.constructor;
4
5
  };
@@ -4,7 +4,9 @@ import "./string.js";
4
4
  import "./boolean.js";
5
5
  import "./array.js";
6
6
  import "./object.js";
7
+ import "./map.js";
7
8
  import "./reflect.js";
9
+ import "./error.js";
8
10
  import {} from "./global.js";
9
11
  //#endregion
10
12
  //#region Field descriptor
@@ -47,25 +49,32 @@ class DescendantDescriptor {
47
49
  //#region Portability metadata
48
50
  class PortabilityMetadata {
49
51
  static #registry = new WeakMap();
50
- #model;
51
52
  #fields = new Map();
52
53
  #descendants = [];
53
54
  #discriminator = "$type";
54
- constructor(model) {
55
- this.#model = model;
55
+ static for(metadata) {
56
+ const registry = PortabilityMetadata.#registry;
57
+ let entry = registry.get(metadata);
58
+ if (entry !== undefined)
59
+ return entry;
60
+ entry = new PortabilityMetadata();
61
+ registry.set(metadata, entry);
62
+ return entry;
56
63
  }
57
64
  static read(model) {
58
- const registry = PortabilityMetadata.#registry;
59
- let metadata = registry.get(model);
60
- if (metadata !== undefined)
61
- return metadata;
62
- metadata = new PortabilityMetadata(model);
63
- registry.set(model, metadata);
65
+ const object = ReferenceError.suppress(model[Symbol.metadata], `Required an implementation of Symbol.metadata in '${model.name}' to use portability`);
66
+ const metadata = PortabilityMetadata.for(object);
67
+ const fields = metadata.#fields;
68
+ let current = object;
69
+ while (true) {
70
+ if (current === null)
71
+ break;
72
+ for (const [key, descriptor] of PortabilityMetadata.for(current).#fields)
73
+ fields.add(key, descriptor);
74
+ current = Object.getPrototypeOf(current);
75
+ }
64
76
  return metadata;
65
77
  }
66
- get model() {
67
- return this.#model;
68
- }
69
78
  get fields() {
70
79
  return this.#fields;
71
80
  }
@@ -150,18 +159,15 @@ export function Field(type, name) {
150
159
  if (typeof (key) === "symbol")
151
160
  throw new TypeError("Symbols are not supported as portable keys");
152
161
  const association = name ?? key;
153
- context.addInitializer(function () {
154
- const model = constructor(this);
155
- const { fields } = PortabilityMetadata.read(model);
156
- if (fields.has(key))
157
- return;
162
+ const { fields } = PortabilityMetadata.for(context.metadata);
163
+ if (!fields.has(key))
158
164
  fields.set(key, new FieldDescriptor(key, association, type));
159
- });
160
165
  };
161
166
  }
162
167
  export function Descendant(descendant, discriminator) {
163
- return function (model) {
164
- const { descendants } = PortabilityMetadata.read(model);
168
+ return function (model, context) {
169
+ void model;
170
+ const { descendants } = PortabilityMetadata.for(context.metadata);
165
171
  descendants.push(new DescendantDescriptor(descendant, discriminator));
166
172
  };
167
173
  }
@@ -170,9 +176,9 @@ export function Descendant(descendant, discriminator) {
170
176
  * @param key The property key to use for the discriminator.
171
177
  */
172
178
  export function DiscriminatorKey(key) {
173
- return function (model) {
174
- const metadata = PortabilityMetadata.read(model);
175
- metadata.discriminator = key;
179
+ return function (model, context) {
180
+ void model;
181
+ PortabilityMetadata.for(context.metadata).discriminator = key;
176
182
  };
177
183
  }
178
184
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adaptive-extender",
3
- "version": "0.10.3",
3
+ "version": "0.10.4",
4
4
  "description": "Adaptive library for JS/TS development environments",
5
5
  "type": "module",
6
6
  "main": "./dist/core/index.js",
@@ -61,12 +61,10 @@
61
61
  "coverage": "vitest run --coverage"
62
62
  },
63
63
  "devDependencies": {
64
- "@babel/plugin-proposal-decorators": "^7.29.7",
65
- "@rolldown/plugin-babel": "^0.2.3",
66
64
  "@types/jsdom": "^21.1.7",
67
65
  "esbuild": "^0.28.0",
68
66
  "jsdom": "^27.0.0",
69
- "typescript": "^6.0.3",
70
- "vitest": "^4.1.8"
67
+ "typescript": "^5.9.3",
68
+ "vitest": "^4.0.10"
71
69
  }
72
70
  }
@@ -1,27 +1,27 @@
1
- {
2
- "compilerOptions": {
3
- /* Language & Environment */
4
- "target": "ES2022",
5
- "module": "ESNext",
6
- "useDefineForClassFields": true,
7
-
8
- /* Module Resolution / Bundler */
9
- "moduleResolution": "bundler",
10
- "moduleDetection": "force",
11
- "verbatimModuleSyntax": true,
12
-
13
- /* Interop & Compatibility */
14
- "esModuleInterop": true,
15
- "allowJs": true,
16
- "skipLibCheck": false,
17
-
18
- /* Type Checking & Linting */
19
- "strict": true,
20
- "strictPropertyInitialization": false,
21
- "noUnusedLocals": false,
22
- "noUnusedParameters": false,
23
-
24
- /* Miscellaneous */
25
- "forceConsistentCasingInFileNames": true,
26
- }
27
- }
1
+ {
2
+ "compilerOptions": {
3
+ /* Language & Environment */
4
+ "target": "ES2022",
5
+ "module": "ESNext",
6
+ "useDefineForClassFields": true,
7
+
8
+ /* Module Resolution / Bundler */
9
+ "moduleResolution": "bundler",
10
+ "moduleDetection": "force",
11
+ "verbatimModuleSyntax": true,
12
+
13
+ /* Interop & Compatibility */
14
+ "esModuleInterop": true,
15
+ "allowJs": true,
16
+ "skipLibCheck": false,
17
+
18
+ /* Type Checking & Linting */
19
+ "strict": true,
20
+ "strictPropertyInitialization": false,
21
+ "noUnusedLocals": false,
22
+ "noUnusedParameters": false,
23
+
24
+ /* Miscellaneous */
25
+ "forceConsistentCasingInFileNames": true,
26
+ }
27
+ }