@pactor-app/runtime 0.1.0 → 1.1.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 +402 -40
- package/dist/index.d.cts +92 -27
- package/dist/index.d.ts +92 -27
- package/dist/index.js +384 -24
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -120,6 +120,14 @@ var DataStore = class {
|
|
|
120
120
|
}
|
|
121
121
|
return out;
|
|
122
122
|
}
|
|
123
|
+
/** 各数据源的加载状态(loading / error),供表达式作用域的 `dataStatus` 键使用 */
|
|
124
|
+
getAllStatus() {
|
|
125
|
+
const out = {};
|
|
126
|
+
for (const [name, status] of this.statuses) {
|
|
127
|
+
out[name] = { loading: status.loading, error: status.error };
|
|
128
|
+
}
|
|
129
|
+
return out;
|
|
130
|
+
}
|
|
123
131
|
subscribe(listener) {
|
|
124
132
|
this.listeners.add(listener);
|
|
125
133
|
return () => {
|
|
@@ -146,7 +154,8 @@ var DataStore = class {
|
|
|
146
154
|
const previous = this.get(name);
|
|
147
155
|
this.update(name, { loading: true, error: void 0, data: previous.data });
|
|
148
156
|
try {
|
|
149
|
-
const
|
|
157
|
+
const raw = await this.loadByType(config);
|
|
158
|
+
const data = applyOptionMapping(raw, config);
|
|
150
159
|
this.update(name, { loading: false, data, error: void 0 });
|
|
151
160
|
} catch (cause) {
|
|
152
161
|
this.update(name, {
|
|
@@ -212,6 +221,69 @@ var DataStore = class {
|
|
|
212
221
|
}
|
|
213
222
|
}
|
|
214
223
|
};
|
|
224
|
+
function applyOptionMapping(data, config) {
|
|
225
|
+
if (!config.valueField && !config.labelField && !config.disabledField) {
|
|
226
|
+
return data;
|
|
227
|
+
}
|
|
228
|
+
if (!Array.isArray(data)) {
|
|
229
|
+
return data;
|
|
230
|
+
}
|
|
231
|
+
const valueField = config.valueField ?? "value";
|
|
232
|
+
const labelField = config.labelField ?? "label";
|
|
233
|
+
return data.map((item) => {
|
|
234
|
+
if (item === null || typeof item !== "object") {
|
|
235
|
+
return item;
|
|
236
|
+
}
|
|
237
|
+
const record = item;
|
|
238
|
+
return {
|
|
239
|
+
...record,
|
|
240
|
+
label: record[labelField],
|
|
241
|
+
value: record[valueField],
|
|
242
|
+
disabled: config.disabledField ? Boolean(record[config.disabledField]) : Boolean(record.disabled)
|
|
243
|
+
};
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// src/datasource/dsl-source-resolver.ts
|
|
248
|
+
function dslSourceKey(ref) {
|
|
249
|
+
const source = ref.source;
|
|
250
|
+
if (source.type === "service") {
|
|
251
|
+
return `service:${source.service}:${JSON.stringify(source.params ?? {})}`;
|
|
252
|
+
}
|
|
253
|
+
const request = source.request;
|
|
254
|
+
return `http:${(request.method ?? "GET").toUpperCase()}:${request.url}:${JSON.stringify(request.params ?? {})}:${JSON.stringify(request.headers ?? {})}`;
|
|
255
|
+
}
|
|
256
|
+
var DslSourceResolver = class {
|
|
257
|
+
constructor(deps) {
|
|
258
|
+
this.deps = deps;
|
|
259
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
260
|
+
}
|
|
261
|
+
resolve(ref) {
|
|
262
|
+
const key = dslSourceKey(ref);
|
|
263
|
+
let cached = this.cache.get(key);
|
|
264
|
+
if (cached === void 0) {
|
|
265
|
+
cached = this.load(ref);
|
|
266
|
+
this.cache.set(key, cached);
|
|
267
|
+
}
|
|
268
|
+
return cached;
|
|
269
|
+
}
|
|
270
|
+
async load(ref) {
|
|
271
|
+
const scope = this.deps.getScope();
|
|
272
|
+
const source = ref.source;
|
|
273
|
+
if (source.type === "service") {
|
|
274
|
+
const handler = this.deps.services.get(source.service);
|
|
275
|
+
if (!handler) {
|
|
276
|
+
throw new Error(
|
|
277
|
+
`[@pactor-app/runtime] service not registered: "${source.service}"`
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
const params = resolveDeep(source.params ?? {}, scope);
|
|
281
|
+
return handler(params);
|
|
282
|
+
}
|
|
283
|
+
const request = resolveDeep(source.request, scope);
|
|
284
|
+
return this.deps.http.request(request);
|
|
285
|
+
}
|
|
286
|
+
};
|
|
215
287
|
|
|
216
288
|
// src/context/scope.ts
|
|
217
289
|
function buildScope(context, local) {
|
|
@@ -221,6 +293,7 @@ function buildScope(context, local) {
|
|
|
221
293
|
state: context.state.getState(),
|
|
222
294
|
form: context.state.get("form"),
|
|
223
295
|
data: context.data.getAllData(),
|
|
296
|
+
dataStatus: context.data.getAllStatus(),
|
|
224
297
|
route: context.route,
|
|
225
298
|
user: context.user,
|
|
226
299
|
params: context.route.params,
|
|
@@ -330,6 +403,11 @@ function createRuntimeContext(options = {}) {
|
|
|
330
403
|
http,
|
|
331
404
|
getScope: () => buildScope(context)
|
|
332
405
|
});
|
|
406
|
+
const dslSources = new DslSourceResolver({
|
|
407
|
+
services,
|
|
408
|
+
http,
|
|
409
|
+
getScope: () => buildScope(context)
|
|
410
|
+
});
|
|
333
411
|
context = {
|
|
334
412
|
app: options.app ?? {},
|
|
335
413
|
page: options.page ?? {},
|
|
@@ -342,9 +420,12 @@ function createRuntimeContext(options = {}) {
|
|
|
342
420
|
actions,
|
|
343
421
|
forms,
|
|
344
422
|
actionResults: {},
|
|
423
|
+
namedActions: options.namedActions ?? {},
|
|
424
|
+
pageComponents: options.pageComponents ?? {},
|
|
345
425
|
permission,
|
|
346
426
|
capabilities,
|
|
347
427
|
http,
|
|
428
|
+
dslSources,
|
|
348
429
|
locale: options.locale ?? "zh-CN",
|
|
349
430
|
i18n: createI18nContext({
|
|
350
431
|
locale: options.locale,
|
|
@@ -360,28 +441,53 @@ import { createI18nContext as createI18nContext2 } from "@pactor-app/core";
|
|
|
360
441
|
import { createContext, useContext } from "react";
|
|
361
442
|
var I18nReactContext = createContext(null);
|
|
362
443
|
var I18nContextProvider = I18nReactContext.Provider;
|
|
363
|
-
var
|
|
364
|
-
|
|
444
|
+
var defaultMessages = {
|
|
445
|
+
"zh-CN": {
|
|
365
446
|
"pactor.layout.expandSidebar": "\u5C55\u5F00\u4FA7\u8FB9\u680F",
|
|
366
447
|
"pactor.layout.collapseSidebar": "\u6536\u8D77\u4FA7\u8FB9\u680F",
|
|
448
|
+
"pactor.layout.openNavigation": "\u6253\u5F00\u5BFC\u822A",
|
|
367
449
|
"pactor.layout.closeTab": "\u5173\u95ED {{title}}",
|
|
368
450
|
"pactor.layout.breadcrumb": "\u9762\u5305\u5C51",
|
|
369
451
|
"pactor.table.loading": "\u52A0\u8F7D\u4E2D\u2026",
|
|
370
452
|
"pactor.table.empty": "\u6682\u65E0\u6570\u636E",
|
|
371
453
|
"pactor.form.required": "\u5FC5\u586B",
|
|
372
|
-
"pactor.select.clear": "\u6E05\u9664"
|
|
454
|
+
"pactor.select.clear": "\u6E05\u9664",
|
|
455
|
+
"pactor.alertDialog.confirm": "\u786E\u5B9A",
|
|
456
|
+
"pactor.alertDialog.cancel": "\u53D6\u6D88",
|
|
457
|
+
"pactor.command.empty": "\u65E0\u5339\u914D\u7ED3\u679C",
|
|
458
|
+
"pactor.overlay.close": "\u5173\u95ED"
|
|
459
|
+
},
|
|
460
|
+
"en-US": {
|
|
461
|
+
"pactor.layout.expandSidebar": "Expand sidebar",
|
|
462
|
+
"pactor.layout.collapseSidebar": "Collapse sidebar",
|
|
463
|
+
"pactor.layout.openNavigation": "Open navigation",
|
|
464
|
+
"pactor.layout.closeTab": "Close {{title}}",
|
|
465
|
+
"pactor.layout.breadcrumb": "Breadcrumb",
|
|
466
|
+
"pactor.table.loading": "Loading\u2026",
|
|
467
|
+
"pactor.table.empty": "No data",
|
|
468
|
+
"pactor.form.required": "Required",
|
|
469
|
+
"pactor.select.clear": "Clear",
|
|
470
|
+
"pactor.alertDialog.confirm": "Confirm",
|
|
471
|
+
"pactor.alertDialog.cancel": "Cancel",
|
|
472
|
+
"pactor.command.empty": "No results found",
|
|
473
|
+
"pactor.overlay.close": "Close"
|
|
373
474
|
}
|
|
374
|
-
}
|
|
475
|
+
};
|
|
476
|
+
function createDefaultI18n(locale) {
|
|
477
|
+
return createI18nContext2({ locale, messages: defaultMessages });
|
|
478
|
+
}
|
|
479
|
+
var defaultI18n = createDefaultI18n();
|
|
375
480
|
function useI18n() {
|
|
376
481
|
const value = useContext(I18nReactContext);
|
|
377
482
|
if (value === null) {
|
|
378
483
|
return defaultI18n;
|
|
379
484
|
}
|
|
485
|
+
const fallback = createDefaultI18n(value.locale);
|
|
380
486
|
return {
|
|
381
487
|
...value,
|
|
382
488
|
t: (key, params) => {
|
|
383
489
|
const translated = value.t(key, params);
|
|
384
|
-
return translated === key ?
|
|
490
|
+
return translated === key ? fallback.t(key, params) : translated;
|
|
385
491
|
}
|
|
386
492
|
};
|
|
387
493
|
}
|
|
@@ -446,6 +552,45 @@ function registerBuiltinActions(registry) {
|
|
|
446
552
|
}
|
|
447
553
|
return { ok: true };
|
|
448
554
|
});
|
|
555
|
+
register("call", async (action, ctx) => {
|
|
556
|
+
const name = action.params?.["name"];
|
|
557
|
+
if (typeof name !== "string" || !name) {
|
|
558
|
+
return {
|
|
559
|
+
ok: false,
|
|
560
|
+
error: new Error("[@pactor-app/runtime] call \u52A8\u4F5C\u7F3A\u5C11 name \u53C2\u6570")
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
const target = ctx.context.namedActions[name];
|
|
564
|
+
if (target === void 0) {
|
|
565
|
+
return {
|
|
566
|
+
ok: false,
|
|
567
|
+
error: new Error(
|
|
568
|
+
`[@pactor-app/runtime] unknown named action: "${name}"`
|
|
569
|
+
)
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
const depth = (callDepth.get(ctx.context) ?? 0) + 1;
|
|
573
|
+
if (depth > MAX_CALL_DEPTH) {
|
|
574
|
+
return {
|
|
575
|
+
ok: false,
|
|
576
|
+
error: new Error(
|
|
577
|
+
`[@pactor-app/runtime] call \u5D4C\u5957\u8D85\u8FC7 ${MAX_CALL_DEPTH} \u5C42\uFF08\u7591\u4F3C\u5FAA\u73AF\u5F15\u7528\uFF09: "${name}"`
|
|
578
|
+
)
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
callDepth.set(ctx.context, depth);
|
|
582
|
+
try {
|
|
583
|
+
for (const child of asActions(target)) {
|
|
584
|
+
const result = await ctx.execute(child);
|
|
585
|
+
if (!result.ok) {
|
|
586
|
+
return result;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
return { ok: true };
|
|
590
|
+
} finally {
|
|
591
|
+
callDepth.set(ctx.context, depth - 1);
|
|
592
|
+
}
|
|
593
|
+
});
|
|
449
594
|
register("parallel", async (action, ctx) => {
|
|
450
595
|
const results = await Promise.all(
|
|
451
596
|
asActions(action.params?.["actions"]).map((child) => ctx.execute(child))
|
|
@@ -502,6 +647,8 @@ function asActions(value) {
|
|
|
502
647
|
}
|
|
503
648
|
return [];
|
|
504
649
|
}
|
|
650
|
+
var callDepth = /* @__PURE__ */ new WeakMap();
|
|
651
|
+
var MAX_CALL_DEPTH = 20;
|
|
505
652
|
function isRecord(value) {
|
|
506
653
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
507
654
|
}
|
|
@@ -557,7 +704,7 @@ var ActionEngine = class {
|
|
|
557
704
|
// Renderer 的 resolveProps)保持原样,由各自执行/渲染时
|
|
558
705
|
// 按当时的 state 与作用域求值
|
|
559
706
|
params: resolveDeep(action.params ?? {}, scope, {
|
|
560
|
-
isOpaque: (value) => typeof value["action"] === "string" || typeof value["type"] === "string"
|
|
707
|
+
isOpaque: (value) => typeof value["action"] === "string" || typeof value["type"] === "string" || typeof value["component"] === "string"
|
|
561
708
|
})
|
|
562
709
|
};
|
|
563
710
|
const ctx = {
|
|
@@ -592,15 +739,57 @@ var ActionEngine = class {
|
|
|
592
739
|
};
|
|
593
740
|
|
|
594
741
|
// src/renderer/renderer.tsx
|
|
742
|
+
import { isDslSourceRef } from "@pactor-app/core";
|
|
595
743
|
import {
|
|
596
744
|
resolveTemplate as resolveTemplate3
|
|
597
745
|
} from "@pactor-app/expression";
|
|
746
|
+
import { validateDslNode, validateDslNodes } from "@pactor-app/schema";
|
|
598
747
|
import {
|
|
599
748
|
createElement,
|
|
600
749
|
useMemo,
|
|
601
750
|
useSyncExternalStore as useSyncExternalStore2
|
|
602
751
|
} from "react";
|
|
603
752
|
|
|
753
|
+
// src/renderer/dsl-source-boundary.tsx
|
|
754
|
+
import { useEffect, useState } from "react";
|
|
755
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
756
|
+
function DslSourceBoundary({
|
|
757
|
+
context,
|
|
758
|
+
sourceRef,
|
|
759
|
+
placeholder,
|
|
760
|
+
children
|
|
761
|
+
}) {
|
|
762
|
+
const [state, setState] = useState({ status: "loading" });
|
|
763
|
+
const key = dslSourceKey(sourceRef);
|
|
764
|
+
useEffect(() => {
|
|
765
|
+
let cancelled = false;
|
|
766
|
+
setState({ status: "loading" });
|
|
767
|
+
context.dslSources.resolve(sourceRef).then(
|
|
768
|
+
(content) => {
|
|
769
|
+
if (!cancelled) {
|
|
770
|
+
setState({ status: "ready", content });
|
|
771
|
+
}
|
|
772
|
+
},
|
|
773
|
+
(cause) => {
|
|
774
|
+
if (!cancelled) {
|
|
775
|
+
console.warn("[@pactor-app/runtime] DSL \u52A8\u6001\u5F15\u7528\u89E3\u6790\u5931\u8D25", cause);
|
|
776
|
+
setState({ status: "error" });
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
);
|
|
780
|
+
return () => {
|
|
781
|
+
cancelled = true;
|
|
782
|
+
};
|
|
783
|
+
}, [context, key]);
|
|
784
|
+
if (state.status === "ready") {
|
|
785
|
+
return /* @__PURE__ */ jsx(Fragment, { children: children(state.content) });
|
|
786
|
+
}
|
|
787
|
+
if (state.status === "error") {
|
|
788
|
+
return null;
|
|
789
|
+
}
|
|
790
|
+
return /* @__PURE__ */ jsx(Fragment, { children: placeholder ?? null });
|
|
791
|
+
}
|
|
792
|
+
|
|
604
793
|
// src/renderer/renderer-context.ts
|
|
605
794
|
import {
|
|
606
795
|
createContext as createContext2,
|
|
@@ -654,7 +843,7 @@ function UnsupportedComponent({ type }) {
|
|
|
654
843
|
}
|
|
655
844
|
|
|
656
845
|
// src/renderer/renderer.tsx
|
|
657
|
-
import { jsx, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
846
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
658
847
|
function DslRenderer({ context, node, engine, children }) {
|
|
659
848
|
useSyncExternalStore2(
|
|
660
849
|
(onChange) => {
|
|
@@ -676,6 +865,7 @@ function DslRenderer({ context, node, engine, children }) {
|
|
|
676
865
|
context,
|
|
677
866
|
engine: resolvedEngine,
|
|
678
867
|
scope: {},
|
|
868
|
+
referenceStack: [],
|
|
679
869
|
renderChildren: (children2, extraScope) => renderChildrenOf(root, children2, extraScope)
|
|
680
870
|
};
|
|
681
871
|
return root;
|
|
@@ -687,6 +877,44 @@ function DslRenderer({ context, node, engine, children }) {
|
|
|
687
877
|
}
|
|
688
878
|
function renderNode(node, value, key) {
|
|
689
879
|
const scope = buildScope(value.context, value.scope);
|
|
880
|
+
if (node.component !== void 0) {
|
|
881
|
+
const name = node.component;
|
|
882
|
+
const stack = value.referenceStack ?? [];
|
|
883
|
+
if (stack.includes(name)) {
|
|
884
|
+
console.warn(
|
|
885
|
+
`[@pactor-app/runtime] \u7EC4\u4EF6\u5F15\u7528\u5FAA\u73AF\uFF1A${[...stack, name].join(" \u2192 ")}`
|
|
886
|
+
);
|
|
887
|
+
return null;
|
|
888
|
+
}
|
|
889
|
+
const subtree = value.context.pageComponents[name];
|
|
890
|
+
if (!subtree) {
|
|
891
|
+
return /* @__PURE__ */ jsx2(UnsupportedComponent, { type: `component(${name})` }, key);
|
|
892
|
+
}
|
|
893
|
+
const scoped = {
|
|
894
|
+
...value,
|
|
895
|
+
referenceStack: [...stack, name]
|
|
896
|
+
};
|
|
897
|
+
scoped.renderChildren = (children, extraScope) => renderChildrenOf(scoped, children, extraScope);
|
|
898
|
+
if (isDslSourceRef(subtree)) {
|
|
899
|
+
const ref = subtree;
|
|
900
|
+
return /* @__PURE__ */ jsx2(RendererContextProvider, { value: scoped, children: /* @__PURE__ */ jsx2(
|
|
901
|
+
DslSourceBoundary,
|
|
902
|
+
{
|
|
903
|
+
context: value.context,
|
|
904
|
+
sourceRef: ref,
|
|
905
|
+
placeholder: ref.placeholder ? renderNode(ref.placeholder, scoped, "placeholder") : null,
|
|
906
|
+
children: (content) => {
|
|
907
|
+
const resolved = validateResolvedNode(content, `components.${name}`);
|
|
908
|
+
if (!resolved) {
|
|
909
|
+
return null;
|
|
910
|
+
}
|
|
911
|
+
return renderNode(mergeReferenceNode(resolved, node), scoped, key);
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
) }, key);
|
|
915
|
+
}
|
|
916
|
+
return /* @__PURE__ */ jsx2(RendererContextProvider, { value: scoped, children: renderNode(mergeReferenceNode(subtree, node), scoped, key) }, key);
|
|
917
|
+
}
|
|
690
918
|
if (node.when !== void 0) {
|
|
691
919
|
const expression = typeof node.when === "string" ? node.when : node.when.expression;
|
|
692
920
|
let visible;
|
|
@@ -713,7 +941,7 @@ function renderNode(node, value, key) {
|
|
|
713
941
|
const entry = value.context.components.get(node.type);
|
|
714
942
|
const normalized = normalizeEntry(entry);
|
|
715
943
|
if (!normalized) {
|
|
716
|
-
return /* @__PURE__ */
|
|
944
|
+
return /* @__PURE__ */ jsx2(UnsupportedComponent, { type: node.type }, key);
|
|
717
945
|
}
|
|
718
946
|
const props = resolveProps(node.props, scope);
|
|
719
947
|
if (node.events) {
|
|
@@ -747,23 +975,102 @@ function resolveDeniedStrategy(permission) {
|
|
|
747
975
|
}
|
|
748
976
|
return "hidden";
|
|
749
977
|
}
|
|
978
|
+
function mergeReferenceNode(definition, reference) {
|
|
979
|
+
return {
|
|
980
|
+
...definition,
|
|
981
|
+
props: { ...definition.props, ...reference.props },
|
|
982
|
+
events: { ...definition.events, ...reference.events },
|
|
983
|
+
when: reference.when ?? definition.when,
|
|
984
|
+
permission: reference.permission ?? definition.permission,
|
|
985
|
+
id: reference.id ?? definition.id
|
|
986
|
+
};
|
|
987
|
+
}
|
|
988
|
+
function validateResolvedNode(content, label) {
|
|
989
|
+
const errors = validateDslNode(content);
|
|
990
|
+
if (errors.length > 0) {
|
|
991
|
+
console.warn(
|
|
992
|
+
`[@pactor-app/runtime] \u52A8\u6001\u5F15\u7528\uFF08${label}\uFF09\u8FD4\u56DE\u5185\u5BB9\u672A\u901A\u8FC7\u6821\u9A8C`,
|
|
993
|
+
errors
|
|
994
|
+
);
|
|
995
|
+
return null;
|
|
996
|
+
}
|
|
997
|
+
return content;
|
|
998
|
+
}
|
|
999
|
+
function validateResolvedNodes(content, label) {
|
|
1000
|
+
const errors = validateDslNodes(content);
|
|
1001
|
+
if (errors.length > 0) {
|
|
1002
|
+
console.warn(
|
|
1003
|
+
`[@pactor-app/runtime] \u52A8\u6001\u5F15\u7528\uFF08${label}\uFF09\u8FD4\u56DE\u5185\u5BB9\u672A\u901A\u8FC7\u6821\u9A8C`,
|
|
1004
|
+
errors
|
|
1005
|
+
);
|
|
1006
|
+
return null;
|
|
1007
|
+
}
|
|
1008
|
+
return content;
|
|
1009
|
+
}
|
|
1010
|
+
function renderChildItem(value, item, key) {
|
|
1011
|
+
if (isDslSourceRef(item)) {
|
|
1012
|
+
const ref = item;
|
|
1013
|
+
return /* @__PURE__ */ jsx2(
|
|
1014
|
+
DslSourceBoundary,
|
|
1015
|
+
{
|
|
1016
|
+
context: value.context,
|
|
1017
|
+
sourceRef: ref,
|
|
1018
|
+
placeholder: ref.placeholder ? renderNode(ref.placeholder, value, "placeholder") : null,
|
|
1019
|
+
children: (content) => {
|
|
1020
|
+
const nodes = validateResolvedNodes(content, "children");
|
|
1021
|
+
if (!nodes) {
|
|
1022
|
+
return null;
|
|
1023
|
+
}
|
|
1024
|
+
return nodes.map(
|
|
1025
|
+
(child, index) => renderChildItem(value, child, isDslSourceRef(child) ? `ref-${index}` : child.id ?? index)
|
|
1026
|
+
);
|
|
1027
|
+
}
|
|
1028
|
+
},
|
|
1029
|
+
key
|
|
1030
|
+
);
|
|
1031
|
+
}
|
|
1032
|
+
return renderNode(item, value, key);
|
|
1033
|
+
}
|
|
750
1034
|
function renderChildrenOf(value, children, extraScope) {
|
|
751
|
-
if (!children || children.length === 0) {
|
|
1035
|
+
if (!children || Array.isArray(children) && children.length === 0) {
|
|
752
1036
|
return null;
|
|
753
1037
|
}
|
|
1038
|
+
if (isDslSourceRef(children)) {
|
|
1039
|
+
const ref = children;
|
|
1040
|
+
return /* @__PURE__ */ jsx2(
|
|
1041
|
+
DslSourceBoundary,
|
|
1042
|
+
{
|
|
1043
|
+
context: value.context,
|
|
1044
|
+
sourceRef: ref,
|
|
1045
|
+
placeholder: ref.placeholder ? renderNode(ref.placeholder, value, "placeholder") : null,
|
|
1046
|
+
children: (content) => {
|
|
1047
|
+
const nodes = validateResolvedNodes(content, "children");
|
|
1048
|
+
if (!nodes) {
|
|
1049
|
+
return null;
|
|
1050
|
+
}
|
|
1051
|
+
return nodes.map(
|
|
1052
|
+
(child, index) => renderChildItem(value, child, isDslSourceRef(child) ? `ref-${index}` : child.id ?? index)
|
|
1053
|
+
);
|
|
1054
|
+
}
|
|
1055
|
+
},
|
|
1056
|
+
"dsl-source"
|
|
1057
|
+
);
|
|
1058
|
+
}
|
|
1059
|
+
const itemKey = (child, index) => isDslSourceRef(child) ? `ref-${index}` : child.id ?? index;
|
|
754
1060
|
if (!extraScope) {
|
|
755
1061
|
return children.map(
|
|
756
|
-
(child, index) =>
|
|
1062
|
+
(child, index) => renderChildItem(value, child, itemKey(child, index))
|
|
757
1063
|
);
|
|
758
1064
|
}
|
|
759
1065
|
const scoped = {
|
|
760
1066
|
context: value.context,
|
|
761
1067
|
engine: value.engine,
|
|
762
1068
|
scope: { ...value.scope, ...extraScope },
|
|
1069
|
+
referenceStack: value.referenceStack,
|
|
763
1070
|
renderChildren: (nested, nestedScope) => renderChildrenOf(scoped, nested, nestedScope)
|
|
764
1071
|
};
|
|
765
|
-
return /* @__PURE__ */
|
|
766
|
-
(child, index) =>
|
|
1072
|
+
return /* @__PURE__ */ jsx2(RendererContextProvider, { value: scoped, children: children.map(
|
|
1073
|
+
(child, index) => renderChildItem(scoped, child, itemKey(child, index))
|
|
767
1074
|
) });
|
|
768
1075
|
}
|
|
769
1076
|
function normalizeEntry(entry) {
|
|
@@ -786,14 +1093,16 @@ function resolveProps(props, scope) {
|
|
|
786
1093
|
return out;
|
|
787
1094
|
}
|
|
788
1095
|
function isEmbeddedDslNode(value) {
|
|
789
|
-
return typeof value.type === "string";
|
|
1096
|
+
return typeof value.type === "string" || typeof value.component === "string";
|
|
790
1097
|
}
|
|
791
1098
|
|
|
792
1099
|
// src/page/page-runtime.tsx
|
|
1100
|
+
import { isDslSourceRef as isDslSourceRef2, resolveRootNodes } from "@pactor-app/core";
|
|
793
1101
|
import {
|
|
1102
|
+
validateDslNodes as validateDslNodes2,
|
|
794
1103
|
validatePageDsl
|
|
795
1104
|
} from "@pactor-app/schema";
|
|
796
|
-
import { Fragment, jsx as
|
|
1105
|
+
import { Fragment as Fragment2, jsx as jsx3 } from "react/jsx-runtime";
|
|
797
1106
|
var PageRuntimeError = class extends Error {
|
|
798
1107
|
constructor(errors) {
|
|
799
1108
|
super(
|
|
@@ -812,7 +1121,9 @@ function createPageRuntime(pageDsl, options = {}) {
|
|
|
812
1121
|
...options,
|
|
813
1122
|
page: pageDsl.page,
|
|
814
1123
|
state: pageDsl.state ?? options.state,
|
|
815
|
-
dataSources: pageDsl.dataSources ?? options.dataSources
|
|
1124
|
+
dataSources: pageDsl.dataSources ?? options.dataSources,
|
|
1125
|
+
namedActions: pageDsl.actions ?? options.namedActions,
|
|
1126
|
+
pageComponents: pageDsl.components ?? options.pageComponents
|
|
816
1127
|
});
|
|
817
1128
|
registerBuiltinActions(context.actions);
|
|
818
1129
|
const engine = new ActionEngine(context);
|
|
@@ -848,10 +1159,7 @@ function createPageRuntime(pageDsl, options = {}) {
|
|
|
848
1159
|
return destroyed;
|
|
849
1160
|
},
|
|
850
1161
|
render() {
|
|
851
|
-
|
|
852
|
-
return null;
|
|
853
|
-
}
|
|
854
|
-
return /* @__PURE__ */ jsx2(DslRenderer, { context, node: pageDsl.body, engine });
|
|
1162
|
+
return renderRoots(pageDsl, context, engine);
|
|
855
1163
|
},
|
|
856
1164
|
ready: () => triggerWhenAlive("onReady"),
|
|
857
1165
|
show: () => triggerWhenAlive("onShow"),
|
|
@@ -879,16 +1187,67 @@ function PageRuntimeView({
|
|
|
879
1187
|
runtime,
|
|
880
1188
|
children
|
|
881
1189
|
}) {
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
1190
|
+
return renderRoots(runtime.pageDsl, runtime.context, runtime.engine, children);
|
|
1191
|
+
}
|
|
1192
|
+
function renderRoots(pageDsl, context, engine, children) {
|
|
1193
|
+
if (!pageDsl.body && isDslSourceRef2(pageDsl.children)) {
|
|
1194
|
+
const ref = pageDsl.children;
|
|
1195
|
+
return /* @__PURE__ */ jsx3(
|
|
1196
|
+
DslSourceBoundary,
|
|
1197
|
+
{
|
|
1198
|
+
context,
|
|
1199
|
+
sourceRef: ref,
|
|
1200
|
+
placeholder: ref.placeholder ? /* @__PURE__ */ jsx3(DslRenderer, { context, node: ref.placeholder, engine }) : null,
|
|
1201
|
+
children: (content) => renderResolvedRoots(content, context, engine, children)
|
|
1202
|
+
}
|
|
1203
|
+
);
|
|
1204
|
+
}
|
|
1205
|
+
const roots = resolveRootNodes(pageDsl);
|
|
1206
|
+
if (roots.length === 0) {
|
|
1207
|
+
return /* @__PURE__ */ jsx3(Fragment2, { children: children ?? null });
|
|
885
1208
|
}
|
|
886
|
-
return
|
|
1209
|
+
return renderRootItems(roots, context, engine, children);
|
|
1210
|
+
}
|
|
1211
|
+
function renderResolvedRoots(content, context, engine, children) {
|
|
1212
|
+
const errors = validateDslNodes2(content);
|
|
1213
|
+
if (errors.length > 0) {
|
|
1214
|
+
console.warn(
|
|
1215
|
+
"[@pactor-app/runtime] \u6839\u7EA7 children \u52A8\u6001\u5F15\u7528\u8FD4\u56DE\u5185\u5BB9\u672A\u901A\u8FC7\u6821\u9A8C",
|
|
1216
|
+
errors
|
|
1217
|
+
);
|
|
1218
|
+
return /* @__PURE__ */ jsx3(Fragment2, { children: children ?? null });
|
|
1219
|
+
}
|
|
1220
|
+
return renderRootItems(content, context, engine, children);
|
|
1221
|
+
}
|
|
1222
|
+
function renderRootItems(items, context, engine, children) {
|
|
1223
|
+
return /* @__PURE__ */ jsx3(Fragment2, { children: items.map(
|
|
1224
|
+
(item, index) => isDslSourceRef2(item) ? /* @__PURE__ */ jsx3(
|
|
1225
|
+
DslSourceBoundary,
|
|
1226
|
+
{
|
|
1227
|
+
context,
|
|
1228
|
+
sourceRef: item,
|
|
1229
|
+
placeholder: item.placeholder ? /* @__PURE__ */ jsx3(DslRenderer, { context, node: item.placeholder, engine }) : null,
|
|
1230
|
+
children: (content) => renderResolvedRoots(content, context, engine, children)
|
|
1231
|
+
},
|
|
1232
|
+
dslSourceKey(item)
|
|
1233
|
+
) : /* @__PURE__ */ jsx3(
|
|
1234
|
+
DslRenderer,
|
|
1235
|
+
{
|
|
1236
|
+
context,
|
|
1237
|
+
node: item,
|
|
1238
|
+
engine,
|
|
1239
|
+
children: index === items.length - 1 ? children : null
|
|
1240
|
+
},
|
|
1241
|
+
item.id ?? index
|
|
1242
|
+
)
|
|
1243
|
+
) });
|
|
887
1244
|
}
|
|
888
1245
|
export {
|
|
889
1246
|
ActionEngine,
|
|
890
1247
|
DataStore,
|
|
891
1248
|
DslRenderer,
|
|
1249
|
+
DslSourceBoundary,
|
|
1250
|
+
DslSourceResolver,
|
|
892
1251
|
I18nContextProvider,
|
|
893
1252
|
PageRuntimeError,
|
|
894
1253
|
PageRuntimeView,
|
|
@@ -900,6 +1259,7 @@ export {
|
|
|
900
1259
|
createFetchHttpAdapter,
|
|
901
1260
|
createPageRuntime,
|
|
902
1261
|
createRuntimeContext,
|
|
1262
|
+
dslSourceKey,
|
|
903
1263
|
registerBuiltinActions,
|
|
904
1264
|
resolveDeep,
|
|
905
1265
|
useDataSource,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pactor-app/runtime",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Pactor runtime: RuntimeContext, StateStore, DataSource runtime, action engine, React renderer and page runtime",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pactor",
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"access": "public"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@pactor-app/core": "
|
|
49
|
-
"@pactor-app/expression": "
|
|
50
|
-
"@pactor-app/schema": "
|
|
48
|
+
"@pactor-app/core": "1.1.0",
|
|
49
|
+
"@pactor-app/expression": "1.1.0",
|
|
50
|
+
"@pactor-app/schema": "1.1.0"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
53
|
"react": ">=18"
|