@rippling/rippling-sdk 0.2.0-alpha.37 → 0.2.0-alpha.39
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/examples/sdui/sdui-crud-todo/sdui-crud-todo.ts +3 -3
- package/examples/sdui/sdui-showcase/sdui-showcase.ts +6 -11
- package/examples/sdui/sdui-tab-multi-view/sdui-tab-multi-view.ts +14 -24
- package/examples/sdui/vote/vote.ts +7 -11
- package/lib/manifest/app.d.mts +11 -1
- package/lib/manifest/app.d.mts.map +1 -1
- package/lib/manifest/app.d.ts +11 -1
- package/lib/manifest/app.d.ts.map +1 -1
- package/lib/manifest/app.js +42 -1
- package/lib/manifest/app.js.map +1 -1
- package/lib/manifest/app.mjs +42 -1
- package/lib/manifest/app.mjs.map +1 -1
- package/lib/manifest/category.d.mts +14 -3
- package/lib/manifest/category.d.mts.map +1 -1
- package/lib/manifest/category.d.ts +14 -3
- package/lib/manifest/category.d.ts.map +1 -1
- package/lib/manifest/category.js +25 -3
- package/lib/manifest/category.js.map +1 -1
- package/lib/manifest/category.mjs +25 -3
- package/lib/manifest/category.mjs.map +1 -1
- package/lib/manifest/custom-object-field-section.d.mts +13 -0
- package/lib/manifest/custom-object-field-section.d.mts.map +1 -1
- package/lib/manifest/custom-object-field-section.d.ts +13 -0
- package/lib/manifest/custom-object-field-section.d.ts.map +1 -1
- package/lib/manifest/custom-object-field-section.js +22 -1
- package/lib/manifest/custom-object-field-section.js.map +1 -1
- package/lib/manifest/custom-object-field-section.mjs +22 -1
- package/lib/manifest/custom-object-field-section.mjs.map +1 -1
- package/lib/manifest/custom-object-page-layout.d.mts +23 -0
- package/lib/manifest/custom-object-page-layout.d.mts.map +1 -1
- package/lib/manifest/custom-object-page-layout.d.ts +23 -0
- package/lib/manifest/custom-object-page-layout.d.ts.map +1 -1
- package/lib/manifest/custom-object-page-layout.js +45 -2
- package/lib/manifest/custom-object-page-layout.js.map +1 -1
- package/lib/manifest/custom-object-page-layout.mjs +45 -2
- package/lib/manifest/custom-object-page-layout.mjs.map +1 -1
- package/lib/manifest/custom-object.d.mts +41 -2
- package/lib/manifest/custom-object.d.mts.map +1 -1
- package/lib/manifest/custom-object.d.ts +41 -2
- package/lib/manifest/custom-object.d.ts.map +1 -1
- package/lib/manifest/custom-object.js +70 -3
- package/lib/manifest/custom-object.js.map +1 -1
- package/lib/manifest/custom-object.mjs +70 -3
- package/lib/manifest/custom-object.mjs.map +1 -1
- package/lib/manifest/existing-manifest-context.d.mts +87 -0
- package/lib/manifest/existing-manifest-context.d.mts.map +1 -0
- package/lib/manifest/existing-manifest-context.d.ts +87 -0
- package/lib/manifest/existing-manifest-context.d.ts.map +1 -0
- package/lib/manifest/existing-manifest-context.js +511 -0
- package/lib/manifest/existing-manifest-context.js.map +1 -0
- package/lib/manifest/existing-manifest-context.mjs +506 -0
- package/lib/manifest/existing-manifest-context.mjs.map +1 -0
- package/lib/manifest/field.d.mts +44 -2
- package/lib/manifest/field.d.mts.map +1 -1
- package/lib/manifest/field.d.ts +44 -2
- package/lib/manifest/field.d.ts.map +1 -1
- package/lib/manifest/field.js +134 -3
- package/lib/manifest/field.js.map +1 -1
- package/lib/manifest/field.mjs +134 -3
- package/lib/manifest/field.mjs.map +1 -1
- package/lib/manifest/index.d.mts +8 -7
- package/lib/manifest/index.d.mts.map +1 -1
- package/lib/manifest/index.d.ts +8 -7
- package/lib/manifest/index.d.ts.map +1 -1
- package/lib/manifest/index.js +3 -1
- package/lib/manifest/index.js.map +1 -1
- package/lib/manifest/index.mjs +5 -4
- package/lib/manifest/index.mjs.map +1 -1
- package/lib/manifest/list-view.d.mts +17 -0
- package/lib/manifest/list-view.d.mts.map +1 -1
- package/lib/manifest/list-view.d.ts +17 -0
- package/lib/manifest/list-view.d.ts.map +1 -1
- package/lib/manifest/list-view.js +38 -1
- package/lib/manifest/list-view.js.map +1 -1
- package/lib/manifest/list-view.mjs +38 -1
- package/lib/manifest/list-view.mjs.map +1 -1
- package/lib/manifest/manifest-builder.d.mts +60 -7
- package/lib/manifest/manifest-builder.d.mts.map +1 -1
- package/lib/manifest/manifest-builder.d.ts +60 -7
- package/lib/manifest/manifest-builder.d.ts.map +1 -1
- package/lib/manifest/manifest-builder.js +62 -4
- package/lib/manifest/manifest-builder.js.map +1 -1
- package/lib/manifest/manifest-builder.mjs +62 -4
- package/lib/manifest/manifest-builder.mjs.map +1 -1
- package/lib/manifest/manifest-function.d.mts +18 -3
- package/lib/manifest/manifest-function.d.mts.map +1 -1
- package/lib/manifest/manifest-function.d.ts +18 -3
- package/lib/manifest/manifest-function.d.ts.map +1 -1
- package/lib/manifest/manifest-function.js +44 -3
- package/lib/manifest/manifest-function.js.map +1 -1
- package/lib/manifest/manifest-function.mjs +44 -3
- package/lib/manifest/manifest-function.mjs.map +1 -1
- package/lib/manifest/rule.d.mts +17 -0
- package/lib/manifest/rule.d.mts.map +1 -1
- package/lib/manifest/rule.d.ts +17 -0
- package/lib/manifest/rule.d.ts.map +1 -1
- package/lib/manifest/rule.js +45 -1
- package/lib/manifest/rule.js.map +1 -1
- package/lib/manifest/rule.mjs +45 -1
- package/lib/manifest/rule.mjs.map +1 -1
- package/lib/manifest/sdui-page.d.mts +10 -1
- package/lib/manifest/sdui-page.d.mts.map +1 -1
- package/lib/manifest/sdui-page.d.ts +10 -1
- package/lib/manifest/sdui-page.d.ts.map +1 -1
- package/lib/manifest/sdui-page.js +28 -1
- package/lib/manifest/sdui-page.js.map +1 -1
- package/lib/manifest/sdui-page.mjs +28 -1
- package/lib/manifest/sdui-page.mjs.map +1 -1
- package/lib/manifest/validation.d.mts +17 -0
- package/lib/manifest/validation.d.mts.map +1 -1
- package/lib/manifest/validation.d.ts +17 -0
- package/lib/manifest/validation.d.ts.map +1 -1
- package/lib/manifest/validation.js +31 -1
- package/lib/manifest/validation.js.map +1 -1
- package/lib/manifest/validation.mjs +31 -1
- package/lib/manifest/validation.mjs.map +1 -1
- package/lib/sdui/actions.d.mts.map +1 -1
- package/lib/sdui/actions.d.ts.map +1 -1
- package/lib/sdui/actions.js +23 -13
- package/lib/sdui/actions.js.map +1 -1
- package/lib/sdui/actions.mjs +23 -13
- package/lib/sdui/actions.mjs.map +1 -1
- package/lib/sdui/component.d.mts +28 -11
- package/lib/sdui/component.d.mts.map +1 -1
- package/lib/sdui/component.d.ts +28 -11
- package/lib/sdui/component.d.ts.map +1 -1
- package/lib/sdui/component.js +69 -36
- package/lib/sdui/component.js.map +1 -1
- package/lib/sdui/component.mjs +69 -36
- package/lib/sdui/component.mjs.map +1 -1
- package/lib/sdui/components.d.mts +1141 -132
- package/lib/sdui/components.d.mts.map +1 -1
- package/lib/sdui/components.d.ts +1141 -132
- package/lib/sdui/components.d.ts.map +1 -1
- package/lib/sdui/components.js +834 -206
- package/lib/sdui/components.js.map +1 -1
- package/lib/sdui/components.mjs +830 -203
- package/lib/sdui/components.mjs.map +1 -1
- package/lib/sdui/directives.d.mts.map +1 -1
- package/lib/sdui/directives.d.ts.map +1 -1
- package/lib/sdui/directives.js +4 -1
- package/lib/sdui/directives.js.map +1 -1
- package/lib/sdui/directives.mjs +4 -1
- package/lib/sdui/directives.mjs.map +1 -1
- package/lib/sdui/index.d.mts +314 -261
- package/lib/sdui/index.d.mts.map +1 -1
- package/lib/sdui/index.d.ts +314 -261
- package/lib/sdui/index.d.ts.map +1 -1
- package/lib/sdui/index.js +255 -204
- package/lib/sdui/index.js.map +1 -1
- package/lib/sdui/index.mjs +128 -103
- package/lib/sdui/index.mjs.map +1 -1
- package/lib/sdui/propTypes.d.mts +6330 -0
- package/lib/sdui/propTypes.d.mts.map +1 -0
- package/lib/sdui/propTypes.d.ts +6330 -0
- package/lib/sdui/propTypes.d.ts.map +1 -0
- package/lib/sdui/propTypes.js +14 -0
- package/lib/sdui/propTypes.js.map +1 -0
- package/lib/sdui/propTypes.mjs +13 -0
- package/lib/sdui/propTypes.mjs.map +1 -0
- package/lib/sdui/render.d.mts +1 -1
- package/lib/sdui/render.d.mts.map +1 -1
- package/lib/sdui/render.d.ts +1 -1
- package/lib/sdui/render.d.ts.map +1 -1
- package/lib/sdui/render.js +11 -3
- package/lib/sdui/render.js.map +1 -1
- package/lib/sdui/render.mjs +11 -3
- package/lib/sdui/render.mjs.map +1 -1
- package/lib/sdui/state.d.mts.map +1 -1
- package/lib/sdui/state.d.ts.map +1 -1
- package/lib/sdui/state.js +3 -1
- package/lib/sdui/state.js.map +1 -1
- package/lib/sdui/state.mjs +3 -1
- package/lib/sdui/state.mjs.map +1 -1
- package/package.json +1 -1
- package/src/lib/manifest/app.ts +46 -2
- package/src/lib/manifest/category.ts +35 -7
- package/src/lib/manifest/custom-object-field-section.ts +37 -1
- package/src/lib/manifest/custom-object-page-layout.ts +67 -2
- package/src/lib/manifest/custom-object.ts +88 -4
- package/src/lib/manifest/existing-manifest-context.ts +673 -0
- package/src/lib/manifest/field.ts +160 -3
- package/src/lib/manifest/index.ts +39 -4
- package/src/lib/manifest/list-view.ts +50 -1
- package/src/lib/manifest/manifest-builder.ts +115 -5
- package/src/lib/manifest/manifest-function.ts +44 -4
- package/src/lib/manifest/rule.ts +60 -1
- package/src/lib/manifest/sdui-page.ts +37 -2
- package/src/lib/manifest/validation.ts +48 -1
- package/src/lib/sdui/actions.ts +23 -10
- package/src/lib/sdui/component.ts +84 -44
- package/src/lib/sdui/components.ts +1627 -212
- package/src/lib/sdui/directives.ts +4 -1
- package/src/lib/sdui/index.ts +565 -200
- package/src/lib/sdui/propTypes.ts +8470 -0
- package/src/lib/sdui/render.ts +13 -5
- package/src/lib/sdui/state.ts +8 -2
- package/src/version.ts +1 -1
- package/version.d.mts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.mjs +1 -1
package/lib/sdui/component.js
CHANGED
|
@@ -2,15 +2,23 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* component() — creates a stateful component boundary.
|
|
4
4
|
*
|
|
5
|
-
* Provides ctx.
|
|
6
|
-
*
|
|
5
|
+
* Provides ctx.localState (scoped local state slot) and ctx.onMount (an
|
|
6
|
+
* action that fires once when the component mounts on the client). The
|
|
7
|
+
* runtime handles state setup and mount firing; consumers don't need to
|
|
8
|
+
* know how the wrapping is implemented.
|
|
9
|
+
*
|
|
10
|
+
* NOTE: these are NOT React hooks. The factory runs ONCE at spec-build
|
|
11
|
+
* time, producing a JSON description of the UI. `localState` returns a
|
|
12
|
+
* path-builder proxy (not a [value, setter] tuple); `onMount` registers
|
|
13
|
+
* a JSON action that fires on first client render (not an effect that
|
|
14
|
+
* re-runs).
|
|
7
15
|
*
|
|
8
16
|
* Usage:
|
|
9
17
|
* function MembersGrid(props) {
|
|
10
18
|
* return component((ctx) => {
|
|
11
|
-
* const local = ctx.
|
|
12
|
-
* ctx.
|
|
13
|
-
* return { element: DataGrid({ ... })
|
|
19
|
+
* const local = ctx.localState({ data: [], loading: true })
|
|
20
|
+
* ctx.onMount(fetchAction)
|
|
21
|
+
* return { element: DataGrid({ ... }) }
|
|
14
22
|
* })
|
|
15
23
|
* }
|
|
16
24
|
*/
|
|
@@ -18,8 +26,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
18
26
|
exports._resetIdCounter = _resetIdCounter;
|
|
19
27
|
exports.component = component;
|
|
20
28
|
let _idCounter = 0;
|
|
29
|
+
// Counter-only IDs (no Date.now()) so the same factory body produces the
|
|
30
|
+
// same paths across runs. The counter is monotonic per process; calling
|
|
31
|
+
// `_resetIdCounter()` (tests only) brings it back to 0 so snapshot tests
|
|
32
|
+
// stay stable.
|
|
21
33
|
function generateId() {
|
|
22
|
-
|
|
34
|
+
_idCounter += 1;
|
|
35
|
+
return `auto_${_idCounter.toString(36)}`;
|
|
23
36
|
}
|
|
24
37
|
// Reset counter (for testing)
|
|
25
38
|
function _resetIdCounter() {
|
|
@@ -45,51 +58,71 @@ function createScopeProxy(basePath) {
|
|
|
45
58
|
return new Proxy({}, handler);
|
|
46
59
|
}
|
|
47
60
|
function component(factory) {
|
|
48
|
-
|
|
49
|
-
|
|
61
|
+
const states = [];
|
|
62
|
+
const mountActions = [];
|
|
50
63
|
const ctx = {
|
|
51
|
-
|
|
64
|
+
localState(initial) {
|
|
52
65
|
const path = `/${generateId()}`;
|
|
53
|
-
|
|
66
|
+
states.push({ path, initial });
|
|
54
67
|
return createScopeProxy(path);
|
|
55
68
|
},
|
|
56
|
-
|
|
57
|
-
|
|
69
|
+
onMount(action) {
|
|
70
|
+
mountActions.push(action);
|
|
58
71
|
},
|
|
59
72
|
};
|
|
60
73
|
const result = factory(ctx);
|
|
61
|
-
//
|
|
62
|
-
|
|
63
|
-
const capturedMount = mountAction;
|
|
64
|
-
// If no local state and no effects, return as-is
|
|
65
|
-
if (!capturedState && !capturedMount) {
|
|
74
|
+
// No state, no effects → return as-is.
|
|
75
|
+
if (states.length === 0 && mountActions.length === 0) {
|
|
66
76
|
return result;
|
|
67
77
|
}
|
|
68
|
-
//
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
78
|
+
// Collapse zero/one/many mount actions for the single onMountAction slot
|
|
79
|
+
// on the innermost wrapper.
|
|
80
|
+
let combinedMount;
|
|
81
|
+
if (mountActions.length === 1) {
|
|
82
|
+
combinedMount = mountActions[0];
|
|
73
83
|
}
|
|
74
|
-
if (
|
|
75
|
-
|
|
84
|
+
else if (mountActions.length > 1) {
|
|
85
|
+
combinedMount = mountActions.flatMap((a) => (Array.isArray(a) ? a : [a]));
|
|
76
86
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if (capturedState) {
|
|
85
|
-
wrapper._localStateRegistration = {
|
|
86
|
-
path: capturedState.path,
|
|
87
|
-
initial: capturedState.initial,
|
|
87
|
+
let wrapped = result.element;
|
|
88
|
+
if (states.length === 0) {
|
|
89
|
+
// Mount-only: a single state-provider wrapper carries onMountAction.
|
|
90
|
+
wrapped = {
|
|
91
|
+
type: '_LocalStateProvider',
|
|
92
|
+
props: combinedMount ? { onMountAction: combinedMount } : {},
|
|
93
|
+
children: [wrapped],
|
|
88
94
|
};
|
|
89
95
|
}
|
|
96
|
+
else {
|
|
97
|
+
// One state-provider wrapper per localState() call, nested
|
|
98
|
+
// innermost-first. Mount actions attach to the innermost wrapper so
|
|
99
|
+
// every state slot is initialized before any action fires.
|
|
100
|
+
for (let i = states.length - 1; i >= 0; i--) {
|
|
101
|
+
const state = states[i];
|
|
102
|
+
if (state) {
|
|
103
|
+
const isInnermost = i === states.length - 1;
|
|
104
|
+
const props = {
|
|
105
|
+
statePath: state.path,
|
|
106
|
+
initialValue: state.initial,
|
|
107
|
+
...(isInnermost && combinedMount ? { onMountAction: combinedMount } : {}),
|
|
108
|
+
};
|
|
109
|
+
const wrapper = {
|
|
110
|
+
type: '_LocalStateProvider',
|
|
111
|
+
props,
|
|
112
|
+
children: [wrapped],
|
|
113
|
+
};
|
|
114
|
+
// render() picks up this marker to populate spec.state.
|
|
115
|
+
wrapper._localStateRegistration = {
|
|
116
|
+
path: state.path,
|
|
117
|
+
initial: state.initial,
|
|
118
|
+
};
|
|
119
|
+
wrapped = wrapper;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
90
123
|
return {
|
|
91
124
|
...result,
|
|
92
|
-
element:
|
|
125
|
+
element: wrapped,
|
|
93
126
|
};
|
|
94
127
|
}
|
|
95
128
|
//# sourceMappingURL=component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.js","sourceRoot":"","sources":["../../src/lib/sdui/component.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"component.js","sourceRoot":"","sources":["../../src/lib/sdui/component.ts"],"names":[],"mappings":"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"}
|
package/lib/sdui/component.mjs
CHANGED
|
@@ -1,21 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* component() — creates a stateful component boundary.
|
|
3
3
|
*
|
|
4
|
-
* Provides ctx.
|
|
5
|
-
*
|
|
4
|
+
* Provides ctx.localState (scoped local state slot) and ctx.onMount (an
|
|
5
|
+
* action that fires once when the component mounts on the client). The
|
|
6
|
+
* runtime handles state setup and mount firing; consumers don't need to
|
|
7
|
+
* know how the wrapping is implemented.
|
|
8
|
+
*
|
|
9
|
+
* NOTE: these are NOT React hooks. The factory runs ONCE at spec-build
|
|
10
|
+
* time, producing a JSON description of the UI. `localState` returns a
|
|
11
|
+
* path-builder proxy (not a [value, setter] tuple); `onMount` registers
|
|
12
|
+
* a JSON action that fires on first client render (not an effect that
|
|
13
|
+
* re-runs).
|
|
6
14
|
*
|
|
7
15
|
* Usage:
|
|
8
16
|
* function MembersGrid(props) {
|
|
9
17
|
* return component((ctx) => {
|
|
10
|
-
* const local = ctx.
|
|
11
|
-
* ctx.
|
|
12
|
-
* return { element: DataGrid({ ... })
|
|
18
|
+
* const local = ctx.localState({ data: [], loading: true })
|
|
19
|
+
* ctx.onMount(fetchAction)
|
|
20
|
+
* return { element: DataGrid({ ... }) }
|
|
13
21
|
* })
|
|
14
22
|
* }
|
|
15
23
|
*/
|
|
16
24
|
let _idCounter = 0;
|
|
25
|
+
// Counter-only IDs (no Date.now()) so the same factory body produces the
|
|
26
|
+
// same paths across runs. The counter is monotonic per process; calling
|
|
27
|
+
// `_resetIdCounter()` (tests only) brings it back to 0 so snapshot tests
|
|
28
|
+
// stay stable.
|
|
17
29
|
function generateId() {
|
|
18
|
-
|
|
30
|
+
_idCounter += 1;
|
|
31
|
+
return `auto_${_idCounter.toString(36)}`;
|
|
19
32
|
}
|
|
20
33
|
// Reset counter (for testing)
|
|
21
34
|
export function _resetIdCounter() {
|
|
@@ -41,51 +54,71 @@ function createScopeProxy(basePath) {
|
|
|
41
54
|
return new Proxy({}, handler);
|
|
42
55
|
}
|
|
43
56
|
export function component(factory) {
|
|
44
|
-
|
|
45
|
-
|
|
57
|
+
const states = [];
|
|
58
|
+
const mountActions = [];
|
|
46
59
|
const ctx = {
|
|
47
|
-
|
|
60
|
+
localState(initial) {
|
|
48
61
|
const path = `/${generateId()}`;
|
|
49
|
-
|
|
62
|
+
states.push({ path, initial });
|
|
50
63
|
return createScopeProxy(path);
|
|
51
64
|
},
|
|
52
|
-
|
|
53
|
-
|
|
65
|
+
onMount(action) {
|
|
66
|
+
mountActions.push(action);
|
|
54
67
|
},
|
|
55
68
|
};
|
|
56
69
|
const result = factory(ctx);
|
|
57
|
-
//
|
|
58
|
-
|
|
59
|
-
const capturedMount = mountAction;
|
|
60
|
-
// If no local state and no effects, return as-is
|
|
61
|
-
if (!capturedState && !capturedMount) {
|
|
70
|
+
// No state, no effects → return as-is.
|
|
71
|
+
if (states.length === 0 && mountActions.length === 0) {
|
|
62
72
|
return result;
|
|
63
73
|
}
|
|
64
|
-
//
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
74
|
+
// Collapse zero/one/many mount actions for the single onMountAction slot
|
|
75
|
+
// on the innermost wrapper.
|
|
76
|
+
let combinedMount;
|
|
77
|
+
if (mountActions.length === 1) {
|
|
78
|
+
combinedMount = mountActions[0];
|
|
69
79
|
}
|
|
70
|
-
if (
|
|
71
|
-
|
|
80
|
+
else if (mountActions.length > 1) {
|
|
81
|
+
combinedMount = mountActions.flatMap((a) => (Array.isArray(a) ? a : [a]));
|
|
72
82
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
if (capturedState) {
|
|
81
|
-
wrapper._localStateRegistration = {
|
|
82
|
-
path: capturedState.path,
|
|
83
|
-
initial: capturedState.initial,
|
|
83
|
+
let wrapped = result.element;
|
|
84
|
+
if (states.length === 0) {
|
|
85
|
+
// Mount-only: a single state-provider wrapper carries onMountAction.
|
|
86
|
+
wrapped = {
|
|
87
|
+
type: '_LocalStateProvider',
|
|
88
|
+
props: combinedMount ? { onMountAction: combinedMount } : {},
|
|
89
|
+
children: [wrapped],
|
|
84
90
|
};
|
|
85
91
|
}
|
|
92
|
+
else {
|
|
93
|
+
// One state-provider wrapper per localState() call, nested
|
|
94
|
+
// innermost-first. Mount actions attach to the innermost wrapper so
|
|
95
|
+
// every state slot is initialized before any action fires.
|
|
96
|
+
for (let i = states.length - 1; i >= 0; i--) {
|
|
97
|
+
const state = states[i];
|
|
98
|
+
if (state) {
|
|
99
|
+
const isInnermost = i === states.length - 1;
|
|
100
|
+
const props = {
|
|
101
|
+
statePath: state.path,
|
|
102
|
+
initialValue: state.initial,
|
|
103
|
+
...(isInnermost && combinedMount ? { onMountAction: combinedMount } : {}),
|
|
104
|
+
};
|
|
105
|
+
const wrapper = {
|
|
106
|
+
type: '_LocalStateProvider',
|
|
107
|
+
props,
|
|
108
|
+
children: [wrapped],
|
|
109
|
+
};
|
|
110
|
+
// render() picks up this marker to populate spec.state.
|
|
111
|
+
wrapper._localStateRegistration = {
|
|
112
|
+
path: state.path,
|
|
113
|
+
initial: state.initial,
|
|
114
|
+
};
|
|
115
|
+
wrapped = wrapper;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
86
119
|
return {
|
|
87
120
|
...result,
|
|
88
|
-
element:
|
|
121
|
+
element: wrapped,
|
|
89
122
|
};
|
|
90
123
|
}
|
|
91
124
|
//# sourceMappingURL=component.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.mjs","sourceRoot":"","sources":["../../src/lib/sdui/component.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"component.mjs","sourceRoot":"","sources":["../../src/lib/sdui/component.ts"],"names":[],"mappings":"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"}
|