@pactor-app/runtime 0.1.0 → 1.0.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 +400 -40
- package/dist/index.d.cts +92 -27
- package/dist/index.d.ts +92 -27
- package/dist/index.js +382 -24
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -23,6 +23,8 @@ __export(index_exports, {
|
|
|
23
23
|
ActionEngine: () => ActionEngine,
|
|
24
24
|
DataStore: () => DataStore,
|
|
25
25
|
DslRenderer: () => DslRenderer,
|
|
26
|
+
DslSourceBoundary: () => DslSourceBoundary,
|
|
27
|
+
DslSourceResolver: () => DslSourceResolver,
|
|
26
28
|
I18nContextProvider: () => I18nContextProvider,
|
|
27
29
|
PageRuntimeError: () => PageRuntimeError,
|
|
28
30
|
PageRuntimeView: () => PageRuntimeView,
|
|
@@ -34,6 +36,7 @@ __export(index_exports, {
|
|
|
34
36
|
createFetchHttpAdapter: () => createFetchHttpAdapter,
|
|
35
37
|
createPageRuntime: () => createPageRuntime,
|
|
36
38
|
createRuntimeContext: () => createRuntimeContext,
|
|
39
|
+
dslSourceKey: () => dslSourceKey,
|
|
37
40
|
registerBuiltinActions: () => registerBuiltinActions,
|
|
38
41
|
resolveDeep: () => resolveDeep,
|
|
39
42
|
useDataSource: () => useDataSource,
|
|
@@ -162,6 +165,14 @@ var DataStore = class {
|
|
|
162
165
|
}
|
|
163
166
|
return out;
|
|
164
167
|
}
|
|
168
|
+
/** 各数据源的加载状态(loading / error),供表达式作用域的 `dataStatus` 键使用 */
|
|
169
|
+
getAllStatus() {
|
|
170
|
+
const out = {};
|
|
171
|
+
for (const [name, status] of this.statuses) {
|
|
172
|
+
out[name] = { loading: status.loading, error: status.error };
|
|
173
|
+
}
|
|
174
|
+
return out;
|
|
175
|
+
}
|
|
165
176
|
subscribe(listener) {
|
|
166
177
|
this.listeners.add(listener);
|
|
167
178
|
return () => {
|
|
@@ -188,7 +199,8 @@ var DataStore = class {
|
|
|
188
199
|
const previous = this.get(name);
|
|
189
200
|
this.update(name, { loading: true, error: void 0, data: previous.data });
|
|
190
201
|
try {
|
|
191
|
-
const
|
|
202
|
+
const raw = await this.loadByType(config);
|
|
203
|
+
const data = applyOptionMapping(raw, config);
|
|
192
204
|
this.update(name, { loading: false, data, error: void 0 });
|
|
193
205
|
} catch (cause) {
|
|
194
206
|
this.update(name, {
|
|
@@ -254,6 +266,69 @@ var DataStore = class {
|
|
|
254
266
|
}
|
|
255
267
|
}
|
|
256
268
|
};
|
|
269
|
+
function applyOptionMapping(data, config) {
|
|
270
|
+
if (!config.valueField && !config.labelField && !config.disabledField) {
|
|
271
|
+
return data;
|
|
272
|
+
}
|
|
273
|
+
if (!Array.isArray(data)) {
|
|
274
|
+
return data;
|
|
275
|
+
}
|
|
276
|
+
const valueField = config.valueField ?? "value";
|
|
277
|
+
const labelField = config.labelField ?? "label";
|
|
278
|
+
return data.map((item) => {
|
|
279
|
+
if (item === null || typeof item !== "object") {
|
|
280
|
+
return item;
|
|
281
|
+
}
|
|
282
|
+
const record = item;
|
|
283
|
+
return {
|
|
284
|
+
...record,
|
|
285
|
+
label: record[labelField],
|
|
286
|
+
value: record[valueField],
|
|
287
|
+
disabled: config.disabledField ? Boolean(record[config.disabledField]) : Boolean(record.disabled)
|
|
288
|
+
};
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// src/datasource/dsl-source-resolver.ts
|
|
293
|
+
function dslSourceKey(ref) {
|
|
294
|
+
const source = ref.source;
|
|
295
|
+
if (source.type === "service") {
|
|
296
|
+
return `service:${source.service}:${JSON.stringify(source.params ?? {})}`;
|
|
297
|
+
}
|
|
298
|
+
const request = source.request;
|
|
299
|
+
return `http:${(request.method ?? "GET").toUpperCase()}:${request.url}:${JSON.stringify(request.params ?? {})}:${JSON.stringify(request.headers ?? {})}`;
|
|
300
|
+
}
|
|
301
|
+
var DslSourceResolver = class {
|
|
302
|
+
constructor(deps) {
|
|
303
|
+
this.deps = deps;
|
|
304
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
305
|
+
}
|
|
306
|
+
resolve(ref) {
|
|
307
|
+
const key = dslSourceKey(ref);
|
|
308
|
+
let cached = this.cache.get(key);
|
|
309
|
+
if (cached === void 0) {
|
|
310
|
+
cached = this.load(ref);
|
|
311
|
+
this.cache.set(key, cached);
|
|
312
|
+
}
|
|
313
|
+
return cached;
|
|
314
|
+
}
|
|
315
|
+
async load(ref) {
|
|
316
|
+
const scope = this.deps.getScope();
|
|
317
|
+
const source = ref.source;
|
|
318
|
+
if (source.type === "service") {
|
|
319
|
+
const handler = this.deps.services.get(source.service);
|
|
320
|
+
if (!handler) {
|
|
321
|
+
throw new Error(
|
|
322
|
+
`[@pactor-app/runtime] service not registered: "${source.service}"`
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
const params = resolveDeep(source.params ?? {}, scope);
|
|
326
|
+
return handler(params);
|
|
327
|
+
}
|
|
328
|
+
const request = resolveDeep(source.request, scope);
|
|
329
|
+
return this.deps.http.request(request);
|
|
330
|
+
}
|
|
331
|
+
};
|
|
257
332
|
|
|
258
333
|
// src/context/scope.ts
|
|
259
334
|
function buildScope(context, local) {
|
|
@@ -263,6 +338,7 @@ function buildScope(context, local) {
|
|
|
263
338
|
state: context.state.getState(),
|
|
264
339
|
form: context.state.get("form"),
|
|
265
340
|
data: context.data.getAllData(),
|
|
341
|
+
dataStatus: context.data.getAllStatus(),
|
|
266
342
|
route: context.route,
|
|
267
343
|
user: context.user,
|
|
268
344
|
params: context.route.params,
|
|
@@ -372,6 +448,11 @@ function createRuntimeContext(options = {}) {
|
|
|
372
448
|
http,
|
|
373
449
|
getScope: () => buildScope(context)
|
|
374
450
|
});
|
|
451
|
+
const dslSources = new DslSourceResolver({
|
|
452
|
+
services,
|
|
453
|
+
http,
|
|
454
|
+
getScope: () => buildScope(context)
|
|
455
|
+
});
|
|
375
456
|
context = {
|
|
376
457
|
app: options.app ?? {},
|
|
377
458
|
page: options.page ?? {},
|
|
@@ -384,9 +465,12 @@ function createRuntimeContext(options = {}) {
|
|
|
384
465
|
actions,
|
|
385
466
|
forms,
|
|
386
467
|
actionResults: {},
|
|
468
|
+
namedActions: options.namedActions ?? {},
|
|
469
|
+
pageComponents: options.pageComponents ?? {},
|
|
387
470
|
permission,
|
|
388
471
|
capabilities,
|
|
389
472
|
http,
|
|
473
|
+
dslSources,
|
|
390
474
|
locale: options.locale ?? "zh-CN",
|
|
391
475
|
i18n: (0, import_core.createI18nContext)({
|
|
392
476
|
locale: options.locale,
|
|
@@ -402,8 +486,8 @@ var import_core2 = require("@pactor-app/core");
|
|
|
402
486
|
var import_react = require("react");
|
|
403
487
|
var I18nReactContext = (0, import_react.createContext)(null);
|
|
404
488
|
var I18nContextProvider = I18nReactContext.Provider;
|
|
405
|
-
var
|
|
406
|
-
|
|
489
|
+
var defaultMessages = {
|
|
490
|
+
"zh-CN": {
|
|
407
491
|
"pactor.layout.expandSidebar": "\u5C55\u5F00\u4FA7\u8FB9\u680F",
|
|
408
492
|
"pactor.layout.collapseSidebar": "\u6536\u8D77\u4FA7\u8FB9\u680F",
|
|
409
493
|
"pactor.layout.closeTab": "\u5173\u95ED {{title}}",
|
|
@@ -411,19 +495,42 @@ var defaultI18n = (0, import_core2.createI18nContext)({
|
|
|
411
495
|
"pactor.table.loading": "\u52A0\u8F7D\u4E2D\u2026",
|
|
412
496
|
"pactor.table.empty": "\u6682\u65E0\u6570\u636E",
|
|
413
497
|
"pactor.form.required": "\u5FC5\u586B",
|
|
414
|
-
"pactor.select.clear": "\u6E05\u9664"
|
|
498
|
+
"pactor.select.clear": "\u6E05\u9664",
|
|
499
|
+
"pactor.alertDialog.confirm": "\u786E\u5B9A",
|
|
500
|
+
"pactor.alertDialog.cancel": "\u53D6\u6D88",
|
|
501
|
+
"pactor.command.empty": "\u65E0\u5339\u914D\u7ED3\u679C",
|
|
502
|
+
"pactor.overlay.close": "\u5173\u95ED"
|
|
503
|
+
},
|
|
504
|
+
"en-US": {
|
|
505
|
+
"pactor.layout.expandSidebar": "Expand sidebar",
|
|
506
|
+
"pactor.layout.collapseSidebar": "Collapse sidebar",
|
|
507
|
+
"pactor.layout.closeTab": "Close {{title}}",
|
|
508
|
+
"pactor.layout.breadcrumb": "Breadcrumb",
|
|
509
|
+
"pactor.table.loading": "Loading\u2026",
|
|
510
|
+
"pactor.table.empty": "No data",
|
|
511
|
+
"pactor.form.required": "Required",
|
|
512
|
+
"pactor.select.clear": "Clear",
|
|
513
|
+
"pactor.alertDialog.confirm": "Confirm",
|
|
514
|
+
"pactor.alertDialog.cancel": "Cancel",
|
|
515
|
+
"pactor.command.empty": "No results found",
|
|
516
|
+
"pactor.overlay.close": "Close"
|
|
415
517
|
}
|
|
416
|
-
}
|
|
518
|
+
};
|
|
519
|
+
function createDefaultI18n(locale) {
|
|
520
|
+
return (0, import_core2.createI18nContext)({ locale, messages: defaultMessages });
|
|
521
|
+
}
|
|
522
|
+
var defaultI18n = createDefaultI18n();
|
|
417
523
|
function useI18n() {
|
|
418
524
|
const value = (0, import_react.useContext)(I18nReactContext);
|
|
419
525
|
if (value === null) {
|
|
420
526
|
return defaultI18n;
|
|
421
527
|
}
|
|
528
|
+
const fallback = createDefaultI18n(value.locale);
|
|
422
529
|
return {
|
|
423
530
|
...value,
|
|
424
531
|
t: (key, params) => {
|
|
425
532
|
const translated = value.t(key, params);
|
|
426
|
-
return translated === key ?
|
|
533
|
+
return translated === key ? fallback.t(key, params) : translated;
|
|
427
534
|
}
|
|
428
535
|
};
|
|
429
536
|
}
|
|
@@ -488,6 +595,45 @@ function registerBuiltinActions(registry) {
|
|
|
488
595
|
}
|
|
489
596
|
return { ok: true };
|
|
490
597
|
});
|
|
598
|
+
register("call", async (action, ctx) => {
|
|
599
|
+
const name = action.params?.["name"];
|
|
600
|
+
if (typeof name !== "string" || !name) {
|
|
601
|
+
return {
|
|
602
|
+
ok: false,
|
|
603
|
+
error: new Error("[@pactor-app/runtime] call \u52A8\u4F5C\u7F3A\u5C11 name \u53C2\u6570")
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
const target = ctx.context.namedActions[name];
|
|
607
|
+
if (target === void 0) {
|
|
608
|
+
return {
|
|
609
|
+
ok: false,
|
|
610
|
+
error: new Error(
|
|
611
|
+
`[@pactor-app/runtime] unknown named action: "${name}"`
|
|
612
|
+
)
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
const depth = (callDepth.get(ctx.context) ?? 0) + 1;
|
|
616
|
+
if (depth > MAX_CALL_DEPTH) {
|
|
617
|
+
return {
|
|
618
|
+
ok: false,
|
|
619
|
+
error: new Error(
|
|
620
|
+
`[@pactor-app/runtime] call \u5D4C\u5957\u8D85\u8FC7 ${MAX_CALL_DEPTH} \u5C42\uFF08\u7591\u4F3C\u5FAA\u73AF\u5F15\u7528\uFF09: "${name}"`
|
|
621
|
+
)
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
callDepth.set(ctx.context, depth);
|
|
625
|
+
try {
|
|
626
|
+
for (const child of asActions(target)) {
|
|
627
|
+
const result = await ctx.execute(child);
|
|
628
|
+
if (!result.ok) {
|
|
629
|
+
return result;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
return { ok: true };
|
|
633
|
+
} finally {
|
|
634
|
+
callDepth.set(ctx.context, depth - 1);
|
|
635
|
+
}
|
|
636
|
+
});
|
|
491
637
|
register("parallel", async (action, ctx) => {
|
|
492
638
|
const results = await Promise.all(
|
|
493
639
|
asActions(action.params?.["actions"]).map((child) => ctx.execute(child))
|
|
@@ -544,6 +690,8 @@ function asActions(value) {
|
|
|
544
690
|
}
|
|
545
691
|
return [];
|
|
546
692
|
}
|
|
693
|
+
var callDepth = /* @__PURE__ */ new WeakMap();
|
|
694
|
+
var MAX_CALL_DEPTH = 20;
|
|
547
695
|
function isRecord(value) {
|
|
548
696
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
549
697
|
}
|
|
@@ -597,7 +745,7 @@ var ActionEngine = class {
|
|
|
597
745
|
// Renderer 的 resolveProps)保持原样,由各自执行/渲染时
|
|
598
746
|
// 按当时的 state 与作用域求值
|
|
599
747
|
params: resolveDeep(action.params ?? {}, scope, {
|
|
600
|
-
isOpaque: (value) => typeof value["action"] === "string" || typeof value["type"] === "string"
|
|
748
|
+
isOpaque: (value) => typeof value["action"] === "string" || typeof value["type"] === "string" || typeof value["component"] === "string"
|
|
601
749
|
})
|
|
602
750
|
};
|
|
603
751
|
const ctx = {
|
|
@@ -632,15 +780,57 @@ var ActionEngine = class {
|
|
|
632
780
|
};
|
|
633
781
|
|
|
634
782
|
// src/renderer/renderer.tsx
|
|
783
|
+
var import_core3 = require("@pactor-app/core");
|
|
635
784
|
var import_expression3 = require("@pactor-app/expression");
|
|
636
|
-
var
|
|
785
|
+
var import_schema = require("@pactor-app/schema");
|
|
786
|
+
var import_react4 = require("react");
|
|
637
787
|
|
|
638
|
-
// src/renderer/
|
|
788
|
+
// src/renderer/dsl-source-boundary.tsx
|
|
639
789
|
var import_react2 = require("react");
|
|
640
|
-
var
|
|
790
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
791
|
+
function DslSourceBoundary({
|
|
792
|
+
context,
|
|
793
|
+
sourceRef,
|
|
794
|
+
placeholder,
|
|
795
|
+
children
|
|
796
|
+
}) {
|
|
797
|
+
const [state, setState] = (0, import_react2.useState)({ status: "loading" });
|
|
798
|
+
const key = dslSourceKey(sourceRef);
|
|
799
|
+
(0, import_react2.useEffect)(() => {
|
|
800
|
+
let cancelled = false;
|
|
801
|
+
setState({ status: "loading" });
|
|
802
|
+
context.dslSources.resolve(sourceRef).then(
|
|
803
|
+
(content) => {
|
|
804
|
+
if (!cancelled) {
|
|
805
|
+
setState({ status: "ready", content });
|
|
806
|
+
}
|
|
807
|
+
},
|
|
808
|
+
(cause) => {
|
|
809
|
+
if (!cancelled) {
|
|
810
|
+
console.warn("[@pactor-app/runtime] DSL \u52A8\u6001\u5F15\u7528\u89E3\u6790\u5931\u8D25", cause);
|
|
811
|
+
setState({ status: "error" });
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
);
|
|
815
|
+
return () => {
|
|
816
|
+
cancelled = true;
|
|
817
|
+
};
|
|
818
|
+
}, [context, key]);
|
|
819
|
+
if (state.status === "ready") {
|
|
820
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: children(state.content) });
|
|
821
|
+
}
|
|
822
|
+
if (state.status === "error") {
|
|
823
|
+
return null;
|
|
824
|
+
}
|
|
825
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: placeholder ?? null });
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
// src/renderer/renderer-context.ts
|
|
829
|
+
var import_react3 = require("react");
|
|
830
|
+
var RendererReactContext = (0, import_react3.createContext)(null);
|
|
641
831
|
var RendererContextProvider = RendererReactContext.Provider;
|
|
642
832
|
function useRenderer() {
|
|
643
|
-
const value = (0,
|
|
833
|
+
const value = (0, import_react3.useContext)(RendererReactContext);
|
|
644
834
|
if (!value) {
|
|
645
835
|
throw new Error("[@pactor-app/runtime] useRenderer \u5FC5\u987B\u5728 <DslRenderer> \u5185\u4F7F\u7528");
|
|
646
836
|
}
|
|
@@ -648,23 +838,23 @@ function useRenderer() {
|
|
|
648
838
|
}
|
|
649
839
|
function useRuntimeState(path) {
|
|
650
840
|
const { context } = useRenderer();
|
|
651
|
-
return (0,
|
|
841
|
+
return (0, import_react3.useSyncExternalStore)(
|
|
652
842
|
(onChange) => context.state.subscribe(onChange),
|
|
653
843
|
() => path === void 0 ? context.state.getState() : context.state.get(path)
|
|
654
844
|
);
|
|
655
845
|
}
|
|
656
846
|
function useDataSource(name) {
|
|
657
847
|
const { context } = useRenderer();
|
|
658
|
-
return (0,
|
|
848
|
+
return (0, import_react3.useSyncExternalStore)(
|
|
659
849
|
(onChange) => context.data.subscribe(onChange),
|
|
660
850
|
() => context.data.get(name)
|
|
661
851
|
);
|
|
662
852
|
}
|
|
663
853
|
|
|
664
854
|
// src/renderer/unsupported.tsx
|
|
665
|
-
var
|
|
855
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
666
856
|
function UnsupportedComponent({ type }) {
|
|
667
|
-
return /* @__PURE__ */ (0,
|
|
857
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
668
858
|
"div",
|
|
669
859
|
{
|
|
670
860
|
"data-pactor-unsupported": type,
|
|
@@ -684,9 +874,9 @@ function UnsupportedComponent({ type }) {
|
|
|
684
874
|
}
|
|
685
875
|
|
|
686
876
|
// src/renderer/renderer.tsx
|
|
687
|
-
var
|
|
877
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
688
878
|
function DslRenderer({ context, node, engine, children }) {
|
|
689
|
-
(0,
|
|
879
|
+
(0, import_react4.useSyncExternalStore)(
|
|
690
880
|
(onChange) => {
|
|
691
881
|
const offState = context.state.subscribe(onChange);
|
|
692
882
|
const offData = context.data.subscribe(onChange);
|
|
@@ -697,26 +887,65 @@ function DslRenderer({ context, node, engine, children }) {
|
|
|
697
887
|
},
|
|
698
888
|
() => `${context.state.getVersion()}:${context.data.getVersion()}`
|
|
699
889
|
);
|
|
700
|
-
const resolvedEngine = (0,
|
|
890
|
+
const resolvedEngine = (0, import_react4.useMemo)(
|
|
701
891
|
() => engine ?? new ActionEngine(context),
|
|
702
892
|
[engine, context]
|
|
703
893
|
);
|
|
704
|
-
const value = (0,
|
|
894
|
+
const value = (0, import_react4.useMemo)(() => {
|
|
705
895
|
const root = {
|
|
706
896
|
context,
|
|
707
897
|
engine: resolvedEngine,
|
|
708
898
|
scope: {},
|
|
899
|
+
referenceStack: [],
|
|
709
900
|
renderChildren: (children2, extraScope) => renderChildrenOf(root, children2, extraScope)
|
|
710
901
|
};
|
|
711
902
|
return root;
|
|
712
903
|
}, [context, resolvedEngine]);
|
|
713
|
-
return /* @__PURE__ */ (0,
|
|
904
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(RendererContextProvider, { value, children: [
|
|
714
905
|
node ? renderNode(node, value, node.id ?? "root") : null,
|
|
715
906
|
children
|
|
716
907
|
] });
|
|
717
908
|
}
|
|
718
909
|
function renderNode(node, value, key) {
|
|
719
910
|
const scope = buildScope(value.context, value.scope);
|
|
911
|
+
if (node.component !== void 0) {
|
|
912
|
+
const name = node.component;
|
|
913
|
+
const stack = value.referenceStack ?? [];
|
|
914
|
+
if (stack.includes(name)) {
|
|
915
|
+
console.warn(
|
|
916
|
+
`[@pactor-app/runtime] \u7EC4\u4EF6\u5F15\u7528\u5FAA\u73AF\uFF1A${[...stack, name].join(" \u2192 ")}`
|
|
917
|
+
);
|
|
918
|
+
return null;
|
|
919
|
+
}
|
|
920
|
+
const subtree = value.context.pageComponents[name];
|
|
921
|
+
if (!subtree) {
|
|
922
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UnsupportedComponent, { type: `component(${name})` }, key);
|
|
923
|
+
}
|
|
924
|
+
const scoped = {
|
|
925
|
+
...value,
|
|
926
|
+
referenceStack: [...stack, name]
|
|
927
|
+
};
|
|
928
|
+
scoped.renderChildren = (children, extraScope) => renderChildrenOf(scoped, children, extraScope);
|
|
929
|
+
if ((0, import_core3.isDslSourceRef)(subtree)) {
|
|
930
|
+
const ref = subtree;
|
|
931
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RendererContextProvider, { value: scoped, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
932
|
+
DslSourceBoundary,
|
|
933
|
+
{
|
|
934
|
+
context: value.context,
|
|
935
|
+
sourceRef: ref,
|
|
936
|
+
placeholder: ref.placeholder ? renderNode(ref.placeholder, scoped, "placeholder") : null,
|
|
937
|
+
children: (content) => {
|
|
938
|
+
const resolved = validateResolvedNode(content, `components.${name}`);
|
|
939
|
+
if (!resolved) {
|
|
940
|
+
return null;
|
|
941
|
+
}
|
|
942
|
+
return renderNode(mergeReferenceNode(resolved, node), scoped, key);
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
) }, key);
|
|
946
|
+
}
|
|
947
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RendererContextProvider, { value: scoped, children: renderNode(mergeReferenceNode(subtree, node), scoped, key) }, key);
|
|
948
|
+
}
|
|
720
949
|
if (node.when !== void 0) {
|
|
721
950
|
const expression = typeof node.when === "string" ? node.when : node.when.expression;
|
|
722
951
|
let visible;
|
|
@@ -743,7 +972,7 @@ function renderNode(node, value, key) {
|
|
|
743
972
|
const entry = value.context.components.get(node.type);
|
|
744
973
|
const normalized = normalizeEntry(entry);
|
|
745
974
|
if (!normalized) {
|
|
746
|
-
return /* @__PURE__ */ (0,
|
|
975
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(UnsupportedComponent, { type: node.type }, key);
|
|
747
976
|
}
|
|
748
977
|
const props = resolveProps(node.props, scope);
|
|
749
978
|
if (node.events) {
|
|
@@ -759,13 +988,13 @@ function renderNode(node, value, key) {
|
|
|
759
988
|
props["readOnly"] = true;
|
|
760
989
|
}
|
|
761
990
|
if (normalized.withScope) {
|
|
762
|
-
return (0,
|
|
991
|
+
return (0, import_react4.createElement)(normalized.component, {
|
|
763
992
|
key,
|
|
764
993
|
...props,
|
|
765
994
|
dslChildren: node.children
|
|
766
995
|
});
|
|
767
996
|
}
|
|
768
|
-
return (0,
|
|
997
|
+
return (0, import_react4.createElement)(
|
|
769
998
|
normalized.component,
|
|
770
999
|
{ key, ...props },
|
|
771
1000
|
renderChildrenOf(value, node.children)
|
|
@@ -777,23 +1006,102 @@ function resolveDeniedStrategy(permission) {
|
|
|
777
1006
|
}
|
|
778
1007
|
return "hidden";
|
|
779
1008
|
}
|
|
1009
|
+
function mergeReferenceNode(definition, reference) {
|
|
1010
|
+
return {
|
|
1011
|
+
...definition,
|
|
1012
|
+
props: { ...definition.props, ...reference.props },
|
|
1013
|
+
events: { ...definition.events, ...reference.events },
|
|
1014
|
+
when: reference.when ?? definition.when,
|
|
1015
|
+
permission: reference.permission ?? definition.permission,
|
|
1016
|
+
id: reference.id ?? definition.id
|
|
1017
|
+
};
|
|
1018
|
+
}
|
|
1019
|
+
function validateResolvedNode(content, label) {
|
|
1020
|
+
const errors = (0, import_schema.validateDslNode)(content);
|
|
1021
|
+
if (errors.length > 0) {
|
|
1022
|
+
console.warn(
|
|
1023
|
+
`[@pactor-app/runtime] \u52A8\u6001\u5F15\u7528\uFF08${label}\uFF09\u8FD4\u56DE\u5185\u5BB9\u672A\u901A\u8FC7\u6821\u9A8C`,
|
|
1024
|
+
errors
|
|
1025
|
+
);
|
|
1026
|
+
return null;
|
|
1027
|
+
}
|
|
1028
|
+
return content;
|
|
1029
|
+
}
|
|
1030
|
+
function validateResolvedNodes(content, label) {
|
|
1031
|
+
const errors = (0, import_schema.validateDslNodes)(content);
|
|
1032
|
+
if (errors.length > 0) {
|
|
1033
|
+
console.warn(
|
|
1034
|
+
`[@pactor-app/runtime] \u52A8\u6001\u5F15\u7528\uFF08${label}\uFF09\u8FD4\u56DE\u5185\u5BB9\u672A\u901A\u8FC7\u6821\u9A8C`,
|
|
1035
|
+
errors
|
|
1036
|
+
);
|
|
1037
|
+
return null;
|
|
1038
|
+
}
|
|
1039
|
+
return content;
|
|
1040
|
+
}
|
|
1041
|
+
function renderChildItem(value, item, key) {
|
|
1042
|
+
if ((0, import_core3.isDslSourceRef)(item)) {
|
|
1043
|
+
const ref = item;
|
|
1044
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1045
|
+
DslSourceBoundary,
|
|
1046
|
+
{
|
|
1047
|
+
context: value.context,
|
|
1048
|
+
sourceRef: ref,
|
|
1049
|
+
placeholder: ref.placeholder ? renderNode(ref.placeholder, value, "placeholder") : null,
|
|
1050
|
+
children: (content) => {
|
|
1051
|
+
const nodes = validateResolvedNodes(content, "children");
|
|
1052
|
+
if (!nodes) {
|
|
1053
|
+
return null;
|
|
1054
|
+
}
|
|
1055
|
+
return nodes.map(
|
|
1056
|
+
(child, index) => renderChildItem(value, child, (0, import_core3.isDslSourceRef)(child) ? `ref-${index}` : child.id ?? index)
|
|
1057
|
+
);
|
|
1058
|
+
}
|
|
1059
|
+
},
|
|
1060
|
+
key
|
|
1061
|
+
);
|
|
1062
|
+
}
|
|
1063
|
+
return renderNode(item, value, key);
|
|
1064
|
+
}
|
|
780
1065
|
function renderChildrenOf(value, children, extraScope) {
|
|
781
|
-
if (!children || children.length === 0) {
|
|
1066
|
+
if (!children || Array.isArray(children) && children.length === 0) {
|
|
782
1067
|
return null;
|
|
783
1068
|
}
|
|
1069
|
+
if ((0, import_core3.isDslSourceRef)(children)) {
|
|
1070
|
+
const ref = children;
|
|
1071
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1072
|
+
DslSourceBoundary,
|
|
1073
|
+
{
|
|
1074
|
+
context: value.context,
|
|
1075
|
+
sourceRef: ref,
|
|
1076
|
+
placeholder: ref.placeholder ? renderNode(ref.placeholder, value, "placeholder") : null,
|
|
1077
|
+
children: (content) => {
|
|
1078
|
+
const nodes = validateResolvedNodes(content, "children");
|
|
1079
|
+
if (!nodes) {
|
|
1080
|
+
return null;
|
|
1081
|
+
}
|
|
1082
|
+
return nodes.map(
|
|
1083
|
+
(child, index) => renderChildItem(value, child, (0, import_core3.isDslSourceRef)(child) ? `ref-${index}` : child.id ?? index)
|
|
1084
|
+
);
|
|
1085
|
+
}
|
|
1086
|
+
},
|
|
1087
|
+
"dsl-source"
|
|
1088
|
+
);
|
|
1089
|
+
}
|
|
1090
|
+
const itemKey = (child, index) => (0, import_core3.isDslSourceRef)(child) ? `ref-${index}` : child.id ?? index;
|
|
784
1091
|
if (!extraScope) {
|
|
785
1092
|
return children.map(
|
|
786
|
-
(child, index) =>
|
|
1093
|
+
(child, index) => renderChildItem(value, child, itemKey(child, index))
|
|
787
1094
|
);
|
|
788
1095
|
}
|
|
789
1096
|
const scoped = {
|
|
790
1097
|
context: value.context,
|
|
791
1098
|
engine: value.engine,
|
|
792
1099
|
scope: { ...value.scope, ...extraScope },
|
|
1100
|
+
referenceStack: value.referenceStack,
|
|
793
1101
|
renderChildren: (nested, nestedScope) => renderChildrenOf(scoped, nested, nestedScope)
|
|
794
1102
|
};
|
|
795
|
-
return /* @__PURE__ */ (0,
|
|
796
|
-
(child, index) =>
|
|
1103
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RendererContextProvider, { value: scoped, children: children.map(
|
|
1104
|
+
(child, index) => renderChildItem(scoped, child, itemKey(child, index))
|
|
797
1105
|
) });
|
|
798
1106
|
}
|
|
799
1107
|
function normalizeEntry(entry) {
|
|
@@ -816,12 +1124,13 @@ function resolveProps(props, scope) {
|
|
|
816
1124
|
return out;
|
|
817
1125
|
}
|
|
818
1126
|
function isEmbeddedDslNode(value) {
|
|
819
|
-
return typeof value.type === "string";
|
|
1127
|
+
return typeof value.type === "string" || typeof value.component === "string";
|
|
820
1128
|
}
|
|
821
1129
|
|
|
822
1130
|
// src/page/page-runtime.tsx
|
|
823
|
-
var
|
|
824
|
-
var
|
|
1131
|
+
var import_core4 = require("@pactor-app/core");
|
|
1132
|
+
var import_schema2 = require("@pactor-app/schema");
|
|
1133
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
825
1134
|
var PageRuntimeError = class extends Error {
|
|
826
1135
|
constructor(errors) {
|
|
827
1136
|
super(
|
|
@@ -832,7 +1141,7 @@ var PageRuntimeError = class extends Error {
|
|
|
832
1141
|
}
|
|
833
1142
|
};
|
|
834
1143
|
function createPageRuntime(pageDsl, options = {}) {
|
|
835
|
-
const validation = (0,
|
|
1144
|
+
const validation = (0, import_schema2.validatePageDsl)(pageDsl);
|
|
836
1145
|
if (!validation.valid) {
|
|
837
1146
|
throw new PageRuntimeError(validation.errors);
|
|
838
1147
|
}
|
|
@@ -840,7 +1149,9 @@ function createPageRuntime(pageDsl, options = {}) {
|
|
|
840
1149
|
...options,
|
|
841
1150
|
page: pageDsl.page,
|
|
842
1151
|
state: pageDsl.state ?? options.state,
|
|
843
|
-
dataSources: pageDsl.dataSources ?? options.dataSources
|
|
1152
|
+
dataSources: pageDsl.dataSources ?? options.dataSources,
|
|
1153
|
+
namedActions: pageDsl.actions ?? options.namedActions,
|
|
1154
|
+
pageComponents: pageDsl.components ?? options.pageComponents
|
|
844
1155
|
});
|
|
845
1156
|
registerBuiltinActions(context.actions);
|
|
846
1157
|
const engine = new ActionEngine(context);
|
|
@@ -876,10 +1187,7 @@ function createPageRuntime(pageDsl, options = {}) {
|
|
|
876
1187
|
return destroyed;
|
|
877
1188
|
},
|
|
878
1189
|
render() {
|
|
879
|
-
|
|
880
|
-
return null;
|
|
881
|
-
}
|
|
882
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DslRenderer, { context, node: pageDsl.body, engine });
|
|
1190
|
+
return renderRoots(pageDsl, context, engine);
|
|
883
1191
|
},
|
|
884
1192
|
ready: () => triggerWhenAlive("onReady"),
|
|
885
1193
|
show: () => triggerWhenAlive("onShow"),
|
|
@@ -907,17 +1215,68 @@ function PageRuntimeView({
|
|
|
907
1215
|
runtime,
|
|
908
1216
|
children
|
|
909
1217
|
}) {
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
1218
|
+
return renderRoots(runtime.pageDsl, runtime.context, runtime.engine, children);
|
|
1219
|
+
}
|
|
1220
|
+
function renderRoots(pageDsl, context, engine, children) {
|
|
1221
|
+
if (!pageDsl.body && (0, import_core4.isDslSourceRef)(pageDsl.children)) {
|
|
1222
|
+
const ref = pageDsl.children;
|
|
1223
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1224
|
+
DslSourceBoundary,
|
|
1225
|
+
{
|
|
1226
|
+
context,
|
|
1227
|
+
sourceRef: ref,
|
|
1228
|
+
placeholder: ref.placeholder ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DslRenderer, { context, node: ref.placeholder, engine }) : null,
|
|
1229
|
+
children: (content) => renderResolvedRoots(content, context, engine, children)
|
|
1230
|
+
}
|
|
1231
|
+
);
|
|
1232
|
+
}
|
|
1233
|
+
const roots = (0, import_core4.resolveRootNodes)(pageDsl);
|
|
1234
|
+
if (roots.length === 0) {
|
|
1235
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: children ?? null });
|
|
913
1236
|
}
|
|
914
|
-
return
|
|
1237
|
+
return renderRootItems(roots, context, engine, children);
|
|
1238
|
+
}
|
|
1239
|
+
function renderResolvedRoots(content, context, engine, children) {
|
|
1240
|
+
const errors = (0, import_schema2.validateDslNodes)(content);
|
|
1241
|
+
if (errors.length > 0) {
|
|
1242
|
+
console.warn(
|
|
1243
|
+
"[@pactor-app/runtime] \u6839\u7EA7 children \u52A8\u6001\u5F15\u7528\u8FD4\u56DE\u5185\u5BB9\u672A\u901A\u8FC7\u6821\u9A8C",
|
|
1244
|
+
errors
|
|
1245
|
+
);
|
|
1246
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: children ?? null });
|
|
1247
|
+
}
|
|
1248
|
+
return renderRootItems(content, context, engine, children);
|
|
1249
|
+
}
|
|
1250
|
+
function renderRootItems(items, context, engine, children) {
|
|
1251
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: items.map(
|
|
1252
|
+
(item, index) => (0, import_core4.isDslSourceRef)(item) ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1253
|
+
DslSourceBoundary,
|
|
1254
|
+
{
|
|
1255
|
+
context,
|
|
1256
|
+
sourceRef: item,
|
|
1257
|
+
placeholder: item.placeholder ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DslRenderer, { context, node: item.placeholder, engine }) : null,
|
|
1258
|
+
children: (content) => renderResolvedRoots(content, context, engine, children)
|
|
1259
|
+
},
|
|
1260
|
+
dslSourceKey(item)
|
|
1261
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1262
|
+
DslRenderer,
|
|
1263
|
+
{
|
|
1264
|
+
context,
|
|
1265
|
+
node: item,
|
|
1266
|
+
engine,
|
|
1267
|
+
children: index === items.length - 1 ? children : null
|
|
1268
|
+
},
|
|
1269
|
+
item.id ?? index
|
|
1270
|
+
)
|
|
1271
|
+
) });
|
|
915
1272
|
}
|
|
916
1273
|
// Annotate the CommonJS export names for ESM import in node:
|
|
917
1274
|
0 && (module.exports = {
|
|
918
1275
|
ActionEngine,
|
|
919
1276
|
DataStore,
|
|
920
1277
|
DslRenderer,
|
|
1278
|
+
DslSourceBoundary,
|
|
1279
|
+
DslSourceResolver,
|
|
921
1280
|
I18nContextProvider,
|
|
922
1281
|
PageRuntimeError,
|
|
923
1282
|
PageRuntimeView,
|
|
@@ -929,6 +1288,7 @@ function PageRuntimeView({
|
|
|
929
1288
|
createFetchHttpAdapter,
|
|
930
1289
|
createPageRuntime,
|
|
931
1290
|
createRuntimeContext,
|
|
1291
|
+
dslSourceKey,
|
|
932
1292
|
registerBuiltinActions,
|
|
933
1293
|
resolveDeep,
|
|
934
1294
|
useDataSource,
|