@domql/utils 3.7.5 → 3.7.6
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/README.md +44 -0
- package/dist/cjs/object.js +30 -0
- package/dist/cjs/scope.js +18 -1
- package/dist/esm/object.js +30 -0
- package/dist/esm/scope.js +18 -1
- package/dist/iife/index.js +48 -1
- package/object.js +43 -0
- package/package.json +2 -2
- package/scope.js +26 -2
package/README.md
CHANGED
|
@@ -70,6 +70,50 @@ if (key === 'childProps') {
|
|
|
70
70
|
|
|
71
71
|
When set on `element.props`, prevents the element from inheriting `childProps` from its parent via `inheritParentProps`. Used by fragment elements to avoid double-application of childProps (since fragments explicitly forward childProps to their children).
|
|
72
72
|
|
|
73
|
+
## Scope (`scope.js`)
|
|
74
|
+
|
|
75
|
+
### `createScope(element, parent)`
|
|
76
|
+
|
|
77
|
+
Creates the scope for an element with prototype-chain inheritance:
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
el.scope → parent.scope → grandparent.scope → ... → root.scope → context.globalScope
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Behavior:**
|
|
84
|
+
- **No own scope** — element inherits `parent.scope` directly (same reference)
|
|
85
|
+
- **Own scope defined** (`scope: { myVar: 1 }`) — prototype is set to parent's scope, chaining up to `globalScope`
|
|
86
|
+
- **No parent/root scope** — new scope created with `Object.create(context.globalScope)`
|
|
87
|
+
- **No context** — plain `{}`
|
|
88
|
+
|
|
89
|
+
### `globalScope`
|
|
90
|
+
|
|
91
|
+
Automatically initialized as `context.globalScope = {}` if context exists. Sits at the bottom of every scope prototype chain, making its properties accessible from any element via `el.scope.X`.
|
|
92
|
+
|
|
93
|
+
```js
|
|
94
|
+
// In context or set by the serialization pipeline:
|
|
95
|
+
context.globalScope = {
|
|
96
|
+
API_URL: 'https://api.example.com',
|
|
97
|
+
helpers: { capitalize: (s) => s[0].toUpperCase() + s.slice(1) }
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Accessible from any element — no import needed:
|
|
101
|
+
onClick: (e, el) => fetch(el.scope.API_URL)
|
|
102
|
+
|
|
103
|
+
// Also directly accessible:
|
|
104
|
+
el.context.globalScope.API_URL
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
When a component defines its own scope, properties shadow parent/global values but the chain remains walkable:
|
|
108
|
+
|
|
109
|
+
```js
|
|
110
|
+
// Parent: scope = { theme: 'dark' }
|
|
111
|
+
// Child: scope = { count: 0 }
|
|
112
|
+
// el.scope.count → 0 (own)
|
|
113
|
+
// el.scope.theme → 'dark' (parent, via prototype)
|
|
114
|
+
// el.scope.API_URL → '...' (globalScope, via prototype chain)
|
|
115
|
+
```
|
|
116
|
+
|
|
73
117
|
## Key Sets (`keys.js`)
|
|
74
118
|
|
|
75
119
|
- **`DOMQ_PROPERTIES`** — Framework-level keys that stay at element root
|
package/dist/cjs/object.js
CHANGED
|
@@ -26,6 +26,7 @@ __export(object_exports, {
|
|
|
26
26
|
deepDestringifyFunctions: () => deepDestringifyFunctions,
|
|
27
27
|
deepMerge: () => deepMerge,
|
|
28
28
|
deepStringifyFunctions: () => deepStringifyFunctions,
|
|
29
|
+
destringifyGlobalScope: () => destringifyGlobalScope,
|
|
29
30
|
detectInfiniteLoop: () => detectInfiniteLoop,
|
|
30
31
|
excludeKeysFromObject: () => excludeKeysFromObject,
|
|
31
32
|
exec: () => exec,
|
|
@@ -337,6 +338,35 @@ const deepDestringifyFunctions = (obj, destringified = {}) => {
|
|
|
337
338
|
}
|
|
338
339
|
return destringified;
|
|
339
340
|
};
|
|
341
|
+
const destringifyGlobalScope = (gs) => {
|
|
342
|
+
if (!gs || typeof gs !== "object") return gs;
|
|
343
|
+
const result = {};
|
|
344
|
+
const fnEntries = [];
|
|
345
|
+
for (const key of Object.keys(gs)) {
|
|
346
|
+
const val = gs[key];
|
|
347
|
+
if ((0, import_types.isString)(val) && hasFunction(val)) {
|
|
348
|
+
fnEntries.push([key, val]);
|
|
349
|
+
} else {
|
|
350
|
+
result[key] = val;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
for (const [key, fnStr] of fnEntries) {
|
|
354
|
+
try {
|
|
355
|
+
const varDecls = Object.keys(result).map((k) => `var ${k} = __gs__[${JSON.stringify(k)}];`).join("\n");
|
|
356
|
+
result[key] = import_globals.window.eval(
|
|
357
|
+
`(function(__gs__) { ${varDecls}
|
|
358
|
+
return (${fnStr}); })`
|
|
359
|
+
)(result);
|
|
360
|
+
} catch (e) {
|
|
361
|
+
try {
|
|
362
|
+
result[key] = import_globals.window.eval(`(${fnStr})`);
|
|
363
|
+
} catch (_) {
|
|
364
|
+
result[key] = fnStr;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
return result;
|
|
369
|
+
};
|
|
340
370
|
const stringToObject = (str, opts = { verbose: true }) => {
|
|
341
371
|
try {
|
|
342
372
|
return str ? import_globals.window.eval("(" + str + ")") : {};
|
package/dist/cjs/scope.js
CHANGED
|
@@ -23,5 +23,22 @@ __export(scope_exports, {
|
|
|
23
23
|
module.exports = __toCommonJS(scope_exports);
|
|
24
24
|
const createScope = (element, parent) => {
|
|
25
25
|
const { __ref: ref } = element;
|
|
26
|
-
|
|
26
|
+
const context = element.context || parent.context || ref.root?.context;
|
|
27
|
+
if (context && !context.globalScope) context.globalScope = {};
|
|
28
|
+
const parentScope = parent.scope || ref.root?.scope;
|
|
29
|
+
const globalScope = context?.globalScope;
|
|
30
|
+
if (!element.scope) {
|
|
31
|
+
if (parentScope) {
|
|
32
|
+
element.scope = parentScope;
|
|
33
|
+
} else if (globalScope) {
|
|
34
|
+
element.scope = Object.create(globalScope);
|
|
35
|
+
} else {
|
|
36
|
+
element.scope = {};
|
|
37
|
+
}
|
|
38
|
+
} else if (typeof element.scope === "object" && element.scope !== null) {
|
|
39
|
+
if (Object.getPrototypeOf(element.scope) === Object.prototype) {
|
|
40
|
+
const proto = parentScope || globalScope;
|
|
41
|
+
if (proto) Object.setPrototypeOf(element.scope, proto);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
27
44
|
};
|
package/dist/esm/object.js
CHANGED
|
@@ -293,6 +293,35 @@ const deepDestringifyFunctions = (obj, destringified = {}) => {
|
|
|
293
293
|
}
|
|
294
294
|
return destringified;
|
|
295
295
|
};
|
|
296
|
+
const destringifyGlobalScope = (gs) => {
|
|
297
|
+
if (!gs || typeof gs !== "object") return gs;
|
|
298
|
+
const result = {};
|
|
299
|
+
const fnEntries = [];
|
|
300
|
+
for (const key of Object.keys(gs)) {
|
|
301
|
+
const val = gs[key];
|
|
302
|
+
if (isString(val) && hasFunction(val)) {
|
|
303
|
+
fnEntries.push([key, val]);
|
|
304
|
+
} else {
|
|
305
|
+
result[key] = val;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
for (const [key, fnStr] of fnEntries) {
|
|
309
|
+
try {
|
|
310
|
+
const varDecls = Object.keys(result).map((k) => `var ${k} = __gs__[${JSON.stringify(k)}];`).join("\n");
|
|
311
|
+
result[key] = window.eval(
|
|
312
|
+
`(function(__gs__) { ${varDecls}
|
|
313
|
+
return (${fnStr}); })`
|
|
314
|
+
)(result);
|
|
315
|
+
} catch (e) {
|
|
316
|
+
try {
|
|
317
|
+
result[key] = window.eval(`(${fnStr})`);
|
|
318
|
+
} catch (_) {
|
|
319
|
+
result[key] = fnStr;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return result;
|
|
324
|
+
};
|
|
296
325
|
const stringToObject = (str, opts = { verbose: true }) => {
|
|
297
326
|
try {
|
|
298
327
|
return str ? window.eval("(" + str + ")") : {};
|
|
@@ -546,6 +575,7 @@ export {
|
|
|
546
575
|
deepDestringifyFunctions,
|
|
547
576
|
deepMerge,
|
|
548
577
|
deepStringifyFunctions,
|
|
578
|
+
destringifyGlobalScope,
|
|
549
579
|
detectInfiniteLoop,
|
|
550
580
|
excludeKeysFromObject,
|
|
551
581
|
exec,
|
package/dist/esm/scope.js
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
const createScope = (element, parent) => {
|
|
2
2
|
const { __ref: ref } = element;
|
|
3
|
-
|
|
3
|
+
const context = element.context || parent.context || ref.root?.context;
|
|
4
|
+
if (context && !context.globalScope) context.globalScope = {};
|
|
5
|
+
const parentScope = parent.scope || ref.root?.scope;
|
|
6
|
+
const globalScope = context?.globalScope;
|
|
7
|
+
if (!element.scope) {
|
|
8
|
+
if (parentScope) {
|
|
9
|
+
element.scope = parentScope;
|
|
10
|
+
} else if (globalScope) {
|
|
11
|
+
element.scope = Object.create(globalScope);
|
|
12
|
+
} else {
|
|
13
|
+
element.scope = {};
|
|
14
|
+
}
|
|
15
|
+
} else if (typeof element.scope === "object" && element.scope !== null) {
|
|
16
|
+
if (Object.getPrototypeOf(element.scope) === Object.prototype) {
|
|
17
|
+
const proto = parentScope || globalScope;
|
|
18
|
+
if (proto) Object.setPrototypeOf(element.scope, proto);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
4
21
|
};
|
|
5
22
|
export {
|
|
6
23
|
createScope
|
package/dist/iife/index.js
CHANGED
|
@@ -1631,6 +1631,7 @@ var DomqlUtils = (() => {
|
|
|
1631
1631
|
deepMergeExtends: () => deepMergeExtends,
|
|
1632
1632
|
deepStringifyFunctions: () => deepStringifyFunctions,
|
|
1633
1633
|
defineSetter: () => defineSetter,
|
|
1634
|
+
destringifyGlobalScope: () => destringifyGlobalScope,
|
|
1634
1635
|
detectInfiniteLoop: () => detectInfiniteLoop,
|
|
1635
1636
|
document: () => document2,
|
|
1636
1637
|
encodeNewlines: () => encodeNewlines,
|
|
@@ -2556,6 +2557,35 @@ var DomqlUtils = (() => {
|
|
|
2556
2557
|
}
|
|
2557
2558
|
return destringified;
|
|
2558
2559
|
};
|
|
2560
|
+
var destringifyGlobalScope = (gs) => {
|
|
2561
|
+
if (!gs || typeof gs !== "object") return gs;
|
|
2562
|
+
const result = {};
|
|
2563
|
+
const fnEntries = [];
|
|
2564
|
+
for (const key of Object.keys(gs)) {
|
|
2565
|
+
const val = gs[key];
|
|
2566
|
+
if (isString(val) && hasFunction(val)) {
|
|
2567
|
+
fnEntries.push([key, val]);
|
|
2568
|
+
} else {
|
|
2569
|
+
result[key] = val;
|
|
2570
|
+
}
|
|
2571
|
+
}
|
|
2572
|
+
for (const [key, fnStr] of fnEntries) {
|
|
2573
|
+
try {
|
|
2574
|
+
const varDecls = Object.keys(result).map((k) => `var ${k} = __gs__[${JSON.stringify(k)}];`).join("\n");
|
|
2575
|
+
result[key] = window2.eval(
|
|
2576
|
+
`(function(__gs__) { ${varDecls}
|
|
2577
|
+
return (${fnStr}); })`
|
|
2578
|
+
)(result);
|
|
2579
|
+
} catch (e) {
|
|
2580
|
+
try {
|
|
2581
|
+
result[key] = window2.eval(`(${fnStr})`);
|
|
2582
|
+
} catch (_) {
|
|
2583
|
+
result[key] = fnStr;
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
return result;
|
|
2588
|
+
};
|
|
2559
2589
|
var stringToObject = (str, opts = { verbose: true }) => {
|
|
2560
2590
|
try {
|
|
2561
2591
|
return str ? window2.eval("(" + str + ")") : {};
|
|
@@ -4078,7 +4108,24 @@ var DomqlUtils = (() => {
|
|
|
4078
4108
|
// scope.js
|
|
4079
4109
|
var createScope = (element, parent) => {
|
|
4080
4110
|
const { __ref: ref } = element;
|
|
4081
|
-
|
|
4111
|
+
const context = element.context || parent.context || ref.root?.context;
|
|
4112
|
+
if (context && !context.globalScope) context.globalScope = {};
|
|
4113
|
+
const parentScope = parent.scope || ref.root?.scope;
|
|
4114
|
+
const globalScope = context?.globalScope;
|
|
4115
|
+
if (!element.scope) {
|
|
4116
|
+
if (parentScope) {
|
|
4117
|
+
element.scope = parentScope;
|
|
4118
|
+
} else if (globalScope) {
|
|
4119
|
+
element.scope = Object.create(globalScope);
|
|
4120
|
+
} else {
|
|
4121
|
+
element.scope = {};
|
|
4122
|
+
}
|
|
4123
|
+
} else if (typeof element.scope === "object" && element.scope !== null) {
|
|
4124
|
+
if (Object.getPrototypeOf(element.scope) === Object.prototype) {
|
|
4125
|
+
const proto = parentScope || globalScope;
|
|
4126
|
+
if (proto) Object.setPrototypeOf(element.scope, proto);
|
|
4127
|
+
}
|
|
4128
|
+
}
|
|
4082
4129
|
};
|
|
4083
4130
|
|
|
4084
4131
|
// triggerEvent.js
|
package/object.js
CHANGED
|
@@ -348,6 +348,49 @@ export const deepDestringifyFunctions = (obj, destringified = {}) => {
|
|
|
348
348
|
return destringified
|
|
349
349
|
}
|
|
350
350
|
|
|
351
|
+
/**
|
|
352
|
+
* Destringify a globalScope object so that function strings become real functions.
|
|
353
|
+
* All globalScope values are made available as local variables when eval'ing each
|
|
354
|
+
* function, so helpers can reference constants and other helpers naturally.
|
|
355
|
+
*/
|
|
356
|
+
export const destringifyGlobalScope = (gs) => {
|
|
357
|
+
if (!gs || typeof gs !== 'object') return gs
|
|
358
|
+
|
|
359
|
+
// First pass: collect non-function values (constants, arrays, objects)
|
|
360
|
+
const result = {}
|
|
361
|
+
const fnEntries = []
|
|
362
|
+
for (const key of Object.keys(gs)) {
|
|
363
|
+
const val = gs[key]
|
|
364
|
+
if (isString(val) && hasFunction(val)) {
|
|
365
|
+
fnEntries.push([key, val])
|
|
366
|
+
} else {
|
|
367
|
+
result[key] = val
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// Second pass: eval functions in a closure with all values in scope
|
|
372
|
+
for (const [key, fnStr] of fnEntries) {
|
|
373
|
+
try {
|
|
374
|
+
// Build a closure that exposes all current globalScope values
|
|
375
|
+
const varDecls = Object.keys(result)
|
|
376
|
+
.map(k => `var ${k} = __gs__[${JSON.stringify(k)}];`)
|
|
377
|
+
.join('\n')
|
|
378
|
+
result[key] = window.eval(
|
|
379
|
+
`(function(__gs__) { ${varDecls}\n return (${fnStr}); })`
|
|
380
|
+
)(result)
|
|
381
|
+
} catch (e) {
|
|
382
|
+
// Fallback: try plain eval
|
|
383
|
+
try {
|
|
384
|
+
result[key] = window.eval(`(${fnStr})`)
|
|
385
|
+
} catch (_) {
|
|
386
|
+
result[key] = fnStr
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
return result
|
|
392
|
+
}
|
|
393
|
+
|
|
351
394
|
export const stringToObject = (str, opts = { verbose: true }) => {
|
|
352
395
|
try {
|
|
353
396
|
return str ? window.eval('(' + str + ')') : {} // eslint-disable-line
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@domql/utils",
|
|
3
|
-
"version": "3.7.
|
|
3
|
+
"version": "3.7.6",
|
|
4
4
|
"license": "CC-BY-NC-4.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"gitHead": "9fc1b79b41cdc725ca6b24aec64920a599634681",
|
|
40
40
|
"peerDependencies": {
|
|
41
|
-
"@symbo.ls/fetch": "^3.7.
|
|
41
|
+
"@symbo.ls/fetch": "^3.7.6"
|
|
42
42
|
},
|
|
43
43
|
"peerDependenciesMeta": {
|
|
44
44
|
"@symbo.ls/fetch": {
|
package/scope.js
CHANGED
|
@@ -1,8 +1,32 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
// Create scope - shared object across the elements to the own or the nearest parent
|
|
4
|
+
// Prototype chain: own scope → parent scope → ... → root scope → globalScope
|
|
4
5
|
export const createScope = (element, parent) => {
|
|
5
6
|
const { __ref: ref } = element
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
const context = element.context || parent.context || ref.root?.context
|
|
8
|
+
|
|
9
|
+
// Ensure globalScope exists on context
|
|
10
|
+
if (context && !context.globalScope) context.globalScope = {}
|
|
11
|
+
|
|
12
|
+
const parentScope = parent.scope || ref.root?.scope
|
|
13
|
+
const globalScope = context?.globalScope
|
|
14
|
+
|
|
15
|
+
if (!element.scope) {
|
|
16
|
+
// No own scope defined — inherit parent scope directly
|
|
17
|
+
if (parentScope) {
|
|
18
|
+
element.scope = parentScope
|
|
19
|
+
} else if (globalScope) {
|
|
20
|
+
// No parent scope either — create root-level scope with globalScope as prototype
|
|
21
|
+
element.scope = Object.create(globalScope)
|
|
22
|
+
} else {
|
|
23
|
+
element.scope = {}
|
|
24
|
+
}
|
|
25
|
+
} else if (typeof element.scope === 'object' && element.scope !== null) {
|
|
26
|
+
// Element defines its own scope — chain prototype to parent scope (or globalScope)
|
|
27
|
+
if (Object.getPrototypeOf(element.scope) === Object.prototype) {
|
|
28
|
+
const proto = parentScope || globalScope
|
|
29
|
+
if (proto) Object.setPrototypeOf(element.scope, proto)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
8
32
|
}
|