@jay-framework/stack-client-runtime 0.13.0 → 0.15.0
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.cjs +137 -18
- package/dist/index.d.ts +26 -4
- package/dist/index.js +137 -18
- package/package.json +8 -8
package/dist/index.cjs
CHANGED
|
@@ -80,24 +80,56 @@ function mergeArraysByTrackBy$1(baseArray, overlayArray, trackByField, trackByMa
|
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
const HEADLESS_INSTANCES = runtime.createJayContext();
|
|
83
|
-
function makeSignals$
|
|
83
|
+
function makeSignals$2(obj) {
|
|
84
84
|
return Object.keys(obj).reduce((signals, key) => {
|
|
85
85
|
signals[key] = component.createSignal(obj[key]);
|
|
86
86
|
return signals;
|
|
87
87
|
}, {});
|
|
88
88
|
}
|
|
89
|
-
function makeHeadlessInstanceComponent(preRender,
|
|
90
|
-
const
|
|
89
|
+
function makeHeadlessInstanceComponent(preRender, componentDef, coordinateKey) {
|
|
90
|
+
const interactiveConstructor = componentDef.comp;
|
|
91
|
+
const resolvedContexts = componentDef.contexts ?? [];
|
|
92
|
+
const clientDefaults = componentDef.clientDefaults;
|
|
93
|
+
const wrappedConstructor = (signalProps, refs, ...pluginResolvedContexts) => {
|
|
91
94
|
const instanceData = runtime.useContext(HEADLESS_INSTANCES);
|
|
92
95
|
const resolvedKey = typeof coordinateKey === "function" ? coordinateKey(runtime.currentConstructionContext()?.dataIds ?? []) : coordinateKey;
|
|
93
|
-
const
|
|
94
|
-
const
|
|
95
|
-
const
|
|
96
|
-
|
|
96
|
+
const suffixKey = resolvedKey.includes("/") && resolvedKey.includes(":") ? resolvedKey.split("/").find((s) => s.includes(":")) ?? resolvedKey : resolvedKey;
|
|
97
|
+
const fastVS = instanceData?.viewStates?.[resolvedKey] ?? instanceData?.viewStates?.[suffixKey];
|
|
98
|
+
const cf = instanceData?.carryForwards?.[resolvedKey] ?? instanceData?.carryForwards?.[suffixKey];
|
|
99
|
+
let resolvedFastVS;
|
|
100
|
+
let resolvedCf;
|
|
101
|
+
if (fastVS) {
|
|
102
|
+
resolvedFastVS = fastVS;
|
|
103
|
+
resolvedCf = cf || {};
|
|
104
|
+
} else if (clientDefaults) {
|
|
105
|
+
const rawProps = signalProps.props();
|
|
106
|
+
const defaults = clientDefaults(rawProps);
|
|
107
|
+
resolvedFastVS = defaults.viewState;
|
|
108
|
+
resolvedCf = defaults.carryForward ?? {};
|
|
109
|
+
} else {
|
|
110
|
+
console.warn(
|
|
111
|
+
`[Jay] Headless instance "${resolvedKey}" has no server data and no clientDefaults. Add .withClientDefaults() to the component definition to provide fallback values.`
|
|
112
|
+
);
|
|
113
|
+
resolvedFastVS = {};
|
|
114
|
+
resolvedCf = {};
|
|
115
|
+
}
|
|
116
|
+
const signalVS = makeSignals$2(resolvedFastVS);
|
|
117
|
+
const compCore = interactiveConstructor(
|
|
118
|
+
signalProps,
|
|
119
|
+
refs,
|
|
120
|
+
signalVS,
|
|
121
|
+
resolvedCf,
|
|
122
|
+
...pluginResolvedContexts
|
|
123
|
+
);
|
|
124
|
+
const originalRender = compCore.render;
|
|
125
|
+
compCore.render = () => {
|
|
126
|
+
return { ...resolvedFastVS, ...originalRender() };
|
|
127
|
+
};
|
|
128
|
+
return compCore;
|
|
97
129
|
};
|
|
98
|
-
return component.makeJayComponent(preRender, wrappedConstructor, ...
|
|
130
|
+
return component.makeJayComponent(preRender, wrappedConstructor, ...resolvedContexts);
|
|
99
131
|
}
|
|
100
|
-
function makeSignals(obj) {
|
|
132
|
+
function makeSignals$1(obj) {
|
|
101
133
|
return Object.keys(obj).reduce((signals, key) => {
|
|
102
134
|
signals[key] = component.createSignal(obj[key]);
|
|
103
135
|
return signals;
|
|
@@ -113,21 +145,19 @@ function makeCompositeJayComponent(preRender, defaultViewState, fastCarryForward
|
|
|
113
145
|
if (headlessInstanceCarryForwards)
|
|
114
146
|
delete fastCarryForward.__headlessInstances;
|
|
115
147
|
const comp = (props, refs, ...contexts) => {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
componentContext.provideContexts.push([HEADLESS_INSTANCES, instancesData]);
|
|
123
|
-
}
|
|
148
|
+
const componentContext = runtime.useContext(component.COMPONENT_CONTEXT);
|
|
149
|
+
const instancesData = {
|
|
150
|
+
viewStates: headlessInstanceViewStates || {},
|
|
151
|
+
carryForwards: headlessInstanceCarryForwards || {}
|
|
152
|
+
};
|
|
153
|
+
componentContext.provideContexts.push([HEADLESS_INSTANCES, instancesData]);
|
|
124
154
|
const instances = interactiveParts.map(
|
|
125
155
|
(part) => {
|
|
126
156
|
const partRefs = part.key ? refs[part.key] : refs;
|
|
127
157
|
let partContexts;
|
|
128
158
|
if (hasFastRendering) {
|
|
129
159
|
const partViewState = part.key ? defaultViewState?.[part.key] : defaultViewState;
|
|
130
|
-
const partFastViewState = partViewState ? makeSignals(partViewState) :
|
|
160
|
+
const partFastViewState = partViewState ? makeSignals$1(partViewState) : makeSignals$1({});
|
|
131
161
|
const partCarryForward = part.key ? fastCarryForward?.[part.key] : fastCarryForward;
|
|
132
162
|
partContexts = [
|
|
133
163
|
partFastViewState,
|
|
@@ -173,6 +203,94 @@ function makeCompositeJayComponent(preRender, defaultViewState, fastCarryForward
|
|
|
173
203
|
...contextMarkers
|
|
174
204
|
);
|
|
175
205
|
}
|
|
206
|
+
function makeSignals(obj) {
|
|
207
|
+
return Object.keys(obj).reduce((signals, key) => {
|
|
208
|
+
signals[key] = component.createSignal(obj[key]);
|
|
209
|
+
return signals;
|
|
210
|
+
}, {});
|
|
211
|
+
}
|
|
212
|
+
function hydrateCompositeJayComponent(hydratePreRender, defaultViewState, fastCarryForward, parts, trackByMap = {}, rootElement) {
|
|
213
|
+
const interactiveParts = parts.filter((part) => part.comp !== void 0);
|
|
214
|
+
const hasFastRendering = defaultViewState !== null && defaultViewState !== void 0;
|
|
215
|
+
const headlessInstanceViewStates = defaultViewState?.__headlessInstances;
|
|
216
|
+
const headlessInstanceCarryForwards = fastCarryForward?.__headlessInstances;
|
|
217
|
+
if (headlessInstanceViewStates)
|
|
218
|
+
delete defaultViewState.__headlessInstances;
|
|
219
|
+
if (headlessInstanceCarryForwards)
|
|
220
|
+
delete fastCarryForward.__headlessInstances;
|
|
221
|
+
const comp = (props, refs, ...contexts) => {
|
|
222
|
+
const componentContext = runtime.useContext(component.COMPONENT_CONTEXT);
|
|
223
|
+
const instancesData = {
|
|
224
|
+
viewStates: headlessInstanceViewStates || {},
|
|
225
|
+
carryForwards: headlessInstanceCarryForwards || {}
|
|
226
|
+
};
|
|
227
|
+
componentContext.provideContexts.push([HEADLESS_INSTANCES, instancesData]);
|
|
228
|
+
const instances = interactiveParts.map(
|
|
229
|
+
(part) => {
|
|
230
|
+
const partRefs = part.key ? refs[part.key] : refs;
|
|
231
|
+
let partContexts;
|
|
232
|
+
if (hasFastRendering) {
|
|
233
|
+
const partViewState = part.key ? defaultViewState?.[part.key] : defaultViewState;
|
|
234
|
+
const partFastViewState = partViewState ? makeSignals(partViewState) : makeSignals({});
|
|
235
|
+
const partCarryForward = part.key ? fastCarryForward?.[part.key] : fastCarryForward;
|
|
236
|
+
partContexts = [
|
|
237
|
+
partFastViewState,
|
|
238
|
+
partCarryForward,
|
|
239
|
+
...contexts.splice(0, part.contextMarkers.length)
|
|
240
|
+
];
|
|
241
|
+
} else {
|
|
242
|
+
partContexts = [...contexts.splice(0, part.contextMarkers.length)];
|
|
243
|
+
}
|
|
244
|
+
return [part.key, part.comp(props, partRefs, ...partContexts)];
|
|
245
|
+
}
|
|
246
|
+
);
|
|
247
|
+
return {
|
|
248
|
+
render: () => {
|
|
249
|
+
let viewState = { ...defaultViewState };
|
|
250
|
+
instances.forEach(([key, instance]) => {
|
|
251
|
+
const rendered = component.materializeViewState(instance.render());
|
|
252
|
+
if (key) {
|
|
253
|
+
viewState[key] = deepMergeViewStates$1(
|
|
254
|
+
defaultViewState[key],
|
|
255
|
+
rendered,
|
|
256
|
+
trackByMap,
|
|
257
|
+
key
|
|
258
|
+
);
|
|
259
|
+
} else {
|
|
260
|
+
viewState = deepMergeViewStates$1(
|
|
261
|
+
viewState,
|
|
262
|
+
rendered,
|
|
263
|
+
trackByMap
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
return viewState;
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
};
|
|
271
|
+
const contextMarkers = interactiveParts.reduce((cm, part) => {
|
|
272
|
+
return [...cm, ...part.contextMarkers];
|
|
273
|
+
}, []);
|
|
274
|
+
const preRender = (options) => {
|
|
275
|
+
const [refs, render] = hydratePreRender(rootElement, options);
|
|
276
|
+
let element;
|
|
277
|
+
const wrappedRender = (viewState) => {
|
|
278
|
+
if (!element) {
|
|
279
|
+
element = render(defaultViewState);
|
|
280
|
+
element.update(viewState);
|
|
281
|
+
} else {
|
|
282
|
+
element.update(viewState);
|
|
283
|
+
}
|
|
284
|
+
return element;
|
|
285
|
+
};
|
|
286
|
+
return [refs, wrappedRender];
|
|
287
|
+
};
|
|
288
|
+
return component.makeJayComponent(
|
|
289
|
+
preRender,
|
|
290
|
+
comp,
|
|
291
|
+
...contextMarkers
|
|
292
|
+
);
|
|
293
|
+
}
|
|
176
294
|
const ACTION_ENDPOINT_BASE = "/_jay/actions";
|
|
177
295
|
class ActionError extends Error {
|
|
178
296
|
constructor(code, message) {
|
|
@@ -570,6 +688,7 @@ exports.AUTOMATION_CONTEXT = AUTOMATION_CONTEXT;
|
|
|
570
688
|
exports.ActionError = ActionError;
|
|
571
689
|
exports.HEADLESS_INSTANCES = HEADLESS_INSTANCES;
|
|
572
690
|
exports.createActionCaller = createActionCaller;
|
|
691
|
+
exports.hydrateCompositeJayComponent = hydrateCompositeJayComponent;
|
|
573
692
|
exports.makeCompositeJayComponent = makeCompositeJayComponent;
|
|
574
693
|
exports.makeHeadlessInstanceComponent = makeHeadlessInstanceComponent;
|
|
575
694
|
exports.setActionCallerOptions = setActionCallerOptions;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as _jay_framework_component from '@jay-framework/component';
|
|
2
|
-
import { ComponentConstructor, ContextMarkers, JayComponentCore } from '@jay-framework/component';
|
|
3
|
-
import { JayElement, PreRenderElement, ContextMarker } from '@jay-framework/runtime';
|
|
2
|
+
import { ComponentConstructor, ContextMarkers, JayComponentCore, ConcreteJayComponent } from '@jay-framework/component';
|
|
3
|
+
import { JayElement, PreRenderElement, RenderElementOptions, RenderElement, ContextMarker } from '@jay-framework/runtime';
|
|
4
4
|
import { TrackByMap } from '@jay-framework/view-state-merge';
|
|
5
5
|
export { AUTOMATION_CONTEXT, AutomationAPI, AutomationWrappedComponent, Coordinate, Interaction, PageState, wrapWithAutomation } from '@jay-framework/runtime-automation';
|
|
6
6
|
|
|
@@ -17,6 +17,15 @@ interface CompositePart {
|
|
|
17
17
|
|
|
18
18
|
declare function makeCompositeJayComponent<PropsT extends object, ViewState extends object, Refs extends object, JayElementT extends JayElement<ViewState, Refs>, CompCore extends JayComponentCore<PropsT, ViewState>>(preRender: PreRenderElement<ViewState, Refs, JayElementT>, defaultViewState: ViewState, fastCarryForward: object, parts: Array<CompositePart>, trackByMap?: TrackByMap): (props: PropsT) => _jay_framework_component.ConcreteJayComponent<PropsT, ViewState, Refs, CompCore, JayElementT>;
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Hydrate variant of makeCompositeJayComponent.
|
|
22
|
+
*
|
|
23
|
+
* Instead of creating new DOM, this adopts the server-rendered DOM by using
|
|
24
|
+
* the hydrate target's function signature: (rootElement, options?) => [Refs, RenderElement].
|
|
25
|
+
* The rootElement is the SSR-rendered DOM already present in the page.
|
|
26
|
+
*/
|
|
27
|
+
declare function hydrateCompositeJayComponent<PropsT extends object, ViewState extends object, Refs extends object, JayElementT extends JayElement<ViewState, Refs>, CompCore extends JayComponentCore<PropsT, ViewState>>(hydratePreRender: (rootElement: Element, options?: RenderElementOptions) => [Refs, RenderElement<ViewState, Refs, JayElementT>], defaultViewState: ViewState, fastCarryForward: object, parts: Array<CompositePart>, trackByMap: TrackByMap, rootElement: Element): (props: PropsT) => _jay_framework_component.ConcreteJayComponent<PropsT, ViewState, Refs, CompCore, JayElementT>;
|
|
28
|
+
|
|
20
29
|
/**
|
|
21
30
|
* Client-side context and helpers for headless component instances.
|
|
22
31
|
*
|
|
@@ -58,7 +67,20 @@ declare const HEADLESS_INSTANCES: ContextMarker<HeadlessInstancesData>;
|
|
|
58
67
|
* (accumulated trackBy values from ancestor forEach loops) and returns the key.
|
|
59
68
|
* @param pluginContexts - Additional context markers from the plugin (if any)
|
|
60
69
|
*/
|
|
61
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Component definition shape expected by makeHeadlessInstanceComponent.
|
|
72
|
+
* `clientDefaults` receives raw props (not signal-wrapped) since it's called
|
|
73
|
+
* before the component construction context is set up.
|
|
74
|
+
*/
|
|
75
|
+
interface HeadlessComponentDef {
|
|
76
|
+
comp: ComponentConstructor<any, any, any, any, any>;
|
|
77
|
+
contexts?: ContextMarkers<any>;
|
|
78
|
+
clientDefaults?: (props: any) => {
|
|
79
|
+
viewState: any;
|
|
80
|
+
carryForward?: any;
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
declare function makeHeadlessInstanceComponent<PropsT extends object, ViewState extends object, Refs extends object, JayElementT extends JayElement<ViewState, Refs>, CompCore extends JayComponentCore<PropsT, ViewState>>(preRender: PreRenderElement<ViewState, Refs, JayElementT>, componentDef: HeadlessComponentDef, coordinateKey: string | ((dataIds: string[]) => string)): (props: PropsT) => ConcreteJayComponent<PropsT, ViewState, Refs, CompCore, JayElementT>;
|
|
62
84
|
|
|
63
85
|
/**
|
|
64
86
|
* Client-side action caller for Jay Stack.
|
|
@@ -125,4 +147,4 @@ declare function setActionCallerOptions(options: ActionCallerOptions): void;
|
|
|
125
147
|
*/
|
|
126
148
|
declare function createActionCaller<Input, Output>(actionName: string, method?: HttpMethod): (input: Input) => Promise<Output>;
|
|
127
149
|
|
|
128
|
-
export { type ActionCallerOptions, ActionError, type CompositePart, HEADLESS_INSTANCES, type HeadlessInstancesData, type HttpMethod, createActionCaller, makeCompositeJayComponent, makeHeadlessInstanceComponent, setActionCallerOptions };
|
|
150
|
+
export { type ActionCallerOptions, ActionError, type CompositePart, HEADLESS_INSTANCES, type HeadlessComponentDef, type HeadlessInstancesData, type HttpMethod, createActionCaller, hydrateCompositeJayComponent, makeCompositeJayComponent, makeHeadlessInstanceComponent, setActionCallerOptions };
|
package/dist/index.js
CHANGED
|
@@ -78,24 +78,56 @@ function mergeArraysByTrackBy$1(baseArray, overlayArray, trackByField, trackByMa
|
|
|
78
78
|
});
|
|
79
79
|
}
|
|
80
80
|
const HEADLESS_INSTANCES = createJayContext();
|
|
81
|
-
function makeSignals$
|
|
81
|
+
function makeSignals$2(obj) {
|
|
82
82
|
return Object.keys(obj).reduce((signals, key) => {
|
|
83
83
|
signals[key] = createSignal(obj[key]);
|
|
84
84
|
return signals;
|
|
85
85
|
}, {});
|
|
86
86
|
}
|
|
87
|
-
function makeHeadlessInstanceComponent(preRender,
|
|
88
|
-
const
|
|
87
|
+
function makeHeadlessInstanceComponent(preRender, componentDef, coordinateKey) {
|
|
88
|
+
const interactiveConstructor = componentDef.comp;
|
|
89
|
+
const resolvedContexts = componentDef.contexts ?? [];
|
|
90
|
+
const clientDefaults = componentDef.clientDefaults;
|
|
91
|
+
const wrappedConstructor = (signalProps, refs, ...pluginResolvedContexts) => {
|
|
89
92
|
const instanceData = useContext(HEADLESS_INSTANCES);
|
|
90
93
|
const resolvedKey = typeof coordinateKey === "function" ? coordinateKey(currentConstructionContext()?.dataIds ?? []) : coordinateKey;
|
|
91
|
-
const
|
|
92
|
-
const
|
|
93
|
-
const
|
|
94
|
-
|
|
94
|
+
const suffixKey = resolvedKey.includes("/") && resolvedKey.includes(":") ? resolvedKey.split("/").find((s) => s.includes(":")) ?? resolvedKey : resolvedKey;
|
|
95
|
+
const fastVS = instanceData?.viewStates?.[resolvedKey] ?? instanceData?.viewStates?.[suffixKey];
|
|
96
|
+
const cf = instanceData?.carryForwards?.[resolvedKey] ?? instanceData?.carryForwards?.[suffixKey];
|
|
97
|
+
let resolvedFastVS;
|
|
98
|
+
let resolvedCf;
|
|
99
|
+
if (fastVS) {
|
|
100
|
+
resolvedFastVS = fastVS;
|
|
101
|
+
resolvedCf = cf || {};
|
|
102
|
+
} else if (clientDefaults) {
|
|
103
|
+
const rawProps = signalProps.props();
|
|
104
|
+
const defaults = clientDefaults(rawProps);
|
|
105
|
+
resolvedFastVS = defaults.viewState;
|
|
106
|
+
resolvedCf = defaults.carryForward ?? {};
|
|
107
|
+
} else {
|
|
108
|
+
console.warn(
|
|
109
|
+
`[Jay] Headless instance "${resolvedKey}" has no server data and no clientDefaults. Add .withClientDefaults() to the component definition to provide fallback values.`
|
|
110
|
+
);
|
|
111
|
+
resolvedFastVS = {};
|
|
112
|
+
resolvedCf = {};
|
|
113
|
+
}
|
|
114
|
+
const signalVS = makeSignals$2(resolvedFastVS);
|
|
115
|
+
const compCore = interactiveConstructor(
|
|
116
|
+
signalProps,
|
|
117
|
+
refs,
|
|
118
|
+
signalVS,
|
|
119
|
+
resolvedCf,
|
|
120
|
+
...pluginResolvedContexts
|
|
121
|
+
);
|
|
122
|
+
const originalRender = compCore.render;
|
|
123
|
+
compCore.render = () => {
|
|
124
|
+
return { ...resolvedFastVS, ...originalRender() };
|
|
125
|
+
};
|
|
126
|
+
return compCore;
|
|
95
127
|
};
|
|
96
|
-
return makeJayComponent(preRender, wrappedConstructor, ...
|
|
128
|
+
return makeJayComponent(preRender, wrappedConstructor, ...resolvedContexts);
|
|
97
129
|
}
|
|
98
|
-
function makeSignals(obj) {
|
|
130
|
+
function makeSignals$1(obj) {
|
|
99
131
|
return Object.keys(obj).reduce((signals, key) => {
|
|
100
132
|
signals[key] = createSignal(obj[key]);
|
|
101
133
|
return signals;
|
|
@@ -111,21 +143,19 @@ function makeCompositeJayComponent(preRender, defaultViewState, fastCarryForward
|
|
|
111
143
|
if (headlessInstanceCarryForwards)
|
|
112
144
|
delete fastCarryForward.__headlessInstances;
|
|
113
145
|
const comp = (props, refs, ...contexts) => {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
componentContext.provideContexts.push([HEADLESS_INSTANCES, instancesData]);
|
|
121
|
-
}
|
|
146
|
+
const componentContext = useContext(COMPONENT_CONTEXT);
|
|
147
|
+
const instancesData = {
|
|
148
|
+
viewStates: headlessInstanceViewStates || {},
|
|
149
|
+
carryForwards: headlessInstanceCarryForwards || {}
|
|
150
|
+
};
|
|
151
|
+
componentContext.provideContexts.push([HEADLESS_INSTANCES, instancesData]);
|
|
122
152
|
const instances = interactiveParts.map(
|
|
123
153
|
(part) => {
|
|
124
154
|
const partRefs = part.key ? refs[part.key] : refs;
|
|
125
155
|
let partContexts;
|
|
126
156
|
if (hasFastRendering) {
|
|
127
157
|
const partViewState = part.key ? defaultViewState?.[part.key] : defaultViewState;
|
|
128
|
-
const partFastViewState = partViewState ? makeSignals(partViewState) :
|
|
158
|
+
const partFastViewState = partViewState ? makeSignals$1(partViewState) : makeSignals$1({});
|
|
129
159
|
const partCarryForward = part.key ? fastCarryForward?.[part.key] : fastCarryForward;
|
|
130
160
|
partContexts = [
|
|
131
161
|
partFastViewState,
|
|
@@ -171,6 +201,94 @@ function makeCompositeJayComponent(preRender, defaultViewState, fastCarryForward
|
|
|
171
201
|
...contextMarkers
|
|
172
202
|
);
|
|
173
203
|
}
|
|
204
|
+
function makeSignals(obj) {
|
|
205
|
+
return Object.keys(obj).reduce((signals, key) => {
|
|
206
|
+
signals[key] = createSignal(obj[key]);
|
|
207
|
+
return signals;
|
|
208
|
+
}, {});
|
|
209
|
+
}
|
|
210
|
+
function hydrateCompositeJayComponent(hydratePreRender, defaultViewState, fastCarryForward, parts, trackByMap = {}, rootElement) {
|
|
211
|
+
const interactiveParts = parts.filter((part) => part.comp !== void 0);
|
|
212
|
+
const hasFastRendering = defaultViewState !== null && defaultViewState !== void 0;
|
|
213
|
+
const headlessInstanceViewStates = defaultViewState?.__headlessInstances;
|
|
214
|
+
const headlessInstanceCarryForwards = fastCarryForward?.__headlessInstances;
|
|
215
|
+
if (headlessInstanceViewStates)
|
|
216
|
+
delete defaultViewState.__headlessInstances;
|
|
217
|
+
if (headlessInstanceCarryForwards)
|
|
218
|
+
delete fastCarryForward.__headlessInstances;
|
|
219
|
+
const comp = (props, refs, ...contexts) => {
|
|
220
|
+
const componentContext = useContext(COMPONENT_CONTEXT);
|
|
221
|
+
const instancesData = {
|
|
222
|
+
viewStates: headlessInstanceViewStates || {},
|
|
223
|
+
carryForwards: headlessInstanceCarryForwards || {}
|
|
224
|
+
};
|
|
225
|
+
componentContext.provideContexts.push([HEADLESS_INSTANCES, instancesData]);
|
|
226
|
+
const instances = interactiveParts.map(
|
|
227
|
+
(part) => {
|
|
228
|
+
const partRefs = part.key ? refs[part.key] : refs;
|
|
229
|
+
let partContexts;
|
|
230
|
+
if (hasFastRendering) {
|
|
231
|
+
const partViewState = part.key ? defaultViewState?.[part.key] : defaultViewState;
|
|
232
|
+
const partFastViewState = partViewState ? makeSignals(partViewState) : makeSignals({});
|
|
233
|
+
const partCarryForward = part.key ? fastCarryForward?.[part.key] : fastCarryForward;
|
|
234
|
+
partContexts = [
|
|
235
|
+
partFastViewState,
|
|
236
|
+
partCarryForward,
|
|
237
|
+
...contexts.splice(0, part.contextMarkers.length)
|
|
238
|
+
];
|
|
239
|
+
} else {
|
|
240
|
+
partContexts = [...contexts.splice(0, part.contextMarkers.length)];
|
|
241
|
+
}
|
|
242
|
+
return [part.key, part.comp(props, partRefs, ...partContexts)];
|
|
243
|
+
}
|
|
244
|
+
);
|
|
245
|
+
return {
|
|
246
|
+
render: () => {
|
|
247
|
+
let viewState = { ...defaultViewState };
|
|
248
|
+
instances.forEach(([key, instance]) => {
|
|
249
|
+
const rendered = materializeViewState(instance.render());
|
|
250
|
+
if (key) {
|
|
251
|
+
viewState[key] = deepMergeViewStates$1(
|
|
252
|
+
defaultViewState[key],
|
|
253
|
+
rendered,
|
|
254
|
+
trackByMap,
|
|
255
|
+
key
|
|
256
|
+
);
|
|
257
|
+
} else {
|
|
258
|
+
viewState = deepMergeViewStates$1(
|
|
259
|
+
viewState,
|
|
260
|
+
rendered,
|
|
261
|
+
trackByMap
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
return viewState;
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
};
|
|
269
|
+
const contextMarkers = interactiveParts.reduce((cm, part) => {
|
|
270
|
+
return [...cm, ...part.contextMarkers];
|
|
271
|
+
}, []);
|
|
272
|
+
const preRender = (options) => {
|
|
273
|
+
const [refs, render] = hydratePreRender(rootElement, options);
|
|
274
|
+
let element;
|
|
275
|
+
const wrappedRender = (viewState) => {
|
|
276
|
+
if (!element) {
|
|
277
|
+
element = render(defaultViewState);
|
|
278
|
+
element.update(viewState);
|
|
279
|
+
} else {
|
|
280
|
+
element.update(viewState);
|
|
281
|
+
}
|
|
282
|
+
return element;
|
|
283
|
+
};
|
|
284
|
+
return [refs, wrappedRender];
|
|
285
|
+
};
|
|
286
|
+
return makeJayComponent(
|
|
287
|
+
preRender,
|
|
288
|
+
comp,
|
|
289
|
+
...contextMarkers
|
|
290
|
+
);
|
|
291
|
+
}
|
|
174
292
|
const ACTION_ENDPOINT_BASE = "/_jay/actions";
|
|
175
293
|
class ActionError extends Error {
|
|
176
294
|
constructor(code, message) {
|
|
@@ -569,6 +687,7 @@ export {
|
|
|
569
687
|
ActionError,
|
|
570
688
|
HEADLESS_INSTANCES,
|
|
571
689
|
createActionCaller,
|
|
690
|
+
hydrateCompositeJayComponent,
|
|
572
691
|
makeCompositeJayComponent,
|
|
573
692
|
makeHeadlessInstanceComponent,
|
|
574
693
|
setActionCallerOptions,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jay-framework/stack-client-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -27,15 +27,15 @@
|
|
|
27
27
|
"test:watch": "vitest"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@jay-framework/component": "^0.
|
|
31
|
-
"@jay-framework/fullstack-component": "^0.
|
|
32
|
-
"@jay-framework/runtime": "^0.
|
|
33
|
-
"@jay-framework/runtime-automation": "^0.
|
|
34
|
-
"@jay-framework/view-state-merge": "^0.
|
|
30
|
+
"@jay-framework/component": "^0.15.0",
|
|
31
|
+
"@jay-framework/fullstack-component": "^0.15.0",
|
|
32
|
+
"@jay-framework/runtime": "^0.15.0",
|
|
33
|
+
"@jay-framework/runtime-automation": "^0.15.0",
|
|
34
|
+
"@jay-framework/view-state-merge": "^0.15.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@jay-framework/dev-environment": "^0.
|
|
38
|
-
"@jay-framework/jay-cli": "^0.
|
|
37
|
+
"@jay-framework/dev-environment": "^0.15.0",
|
|
38
|
+
"@jay-framework/jay-cli": "^0.15.0",
|
|
39
39
|
"@types/express": "^5.0.2",
|
|
40
40
|
"@types/node": "^22.15.21",
|
|
41
41
|
"nodemon": "^3.0.3",
|