@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.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 data = await this.loadByType(config);
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,8 +441,8 @@ 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 defaultI18n = createI18nContext2({
364
- messages: {
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",
367
448
  "pactor.layout.closeTab": "\u5173\u95ED {{title}}",
@@ -369,19 +450,42 @@ var defaultI18n = createI18nContext2({
369
450
  "pactor.table.loading": "\u52A0\u8F7D\u4E2D\u2026",
370
451
  "pactor.table.empty": "\u6682\u65E0\u6570\u636E",
371
452
  "pactor.form.required": "\u5FC5\u586B",
372
- "pactor.select.clear": "\u6E05\u9664"
453
+ "pactor.select.clear": "\u6E05\u9664",
454
+ "pactor.alertDialog.confirm": "\u786E\u5B9A",
455
+ "pactor.alertDialog.cancel": "\u53D6\u6D88",
456
+ "pactor.command.empty": "\u65E0\u5339\u914D\u7ED3\u679C",
457
+ "pactor.overlay.close": "\u5173\u95ED"
458
+ },
459
+ "en-US": {
460
+ "pactor.layout.expandSidebar": "Expand sidebar",
461
+ "pactor.layout.collapseSidebar": "Collapse sidebar",
462
+ "pactor.layout.closeTab": "Close {{title}}",
463
+ "pactor.layout.breadcrumb": "Breadcrumb",
464
+ "pactor.table.loading": "Loading\u2026",
465
+ "pactor.table.empty": "No data",
466
+ "pactor.form.required": "Required",
467
+ "pactor.select.clear": "Clear",
468
+ "pactor.alertDialog.confirm": "Confirm",
469
+ "pactor.alertDialog.cancel": "Cancel",
470
+ "pactor.command.empty": "No results found",
471
+ "pactor.overlay.close": "Close"
373
472
  }
374
- });
473
+ };
474
+ function createDefaultI18n(locale) {
475
+ return createI18nContext2({ locale, messages: defaultMessages });
476
+ }
477
+ var defaultI18n = createDefaultI18n();
375
478
  function useI18n() {
376
479
  const value = useContext(I18nReactContext);
377
480
  if (value === null) {
378
481
  return defaultI18n;
379
482
  }
483
+ const fallback = createDefaultI18n(value.locale);
380
484
  return {
381
485
  ...value,
382
486
  t: (key, params) => {
383
487
  const translated = value.t(key, params);
384
- return translated === key ? defaultI18n.t(key, params) : translated;
488
+ return translated === key ? fallback.t(key, params) : translated;
385
489
  }
386
490
  };
387
491
  }
@@ -446,6 +550,45 @@ function registerBuiltinActions(registry) {
446
550
  }
447
551
  return { ok: true };
448
552
  });
553
+ register("call", async (action, ctx) => {
554
+ const name = action.params?.["name"];
555
+ if (typeof name !== "string" || !name) {
556
+ return {
557
+ ok: false,
558
+ error: new Error("[@pactor-app/runtime] call \u52A8\u4F5C\u7F3A\u5C11 name \u53C2\u6570")
559
+ };
560
+ }
561
+ const target = ctx.context.namedActions[name];
562
+ if (target === void 0) {
563
+ return {
564
+ ok: false,
565
+ error: new Error(
566
+ `[@pactor-app/runtime] unknown named action: "${name}"`
567
+ )
568
+ };
569
+ }
570
+ const depth = (callDepth.get(ctx.context) ?? 0) + 1;
571
+ if (depth > MAX_CALL_DEPTH) {
572
+ return {
573
+ ok: false,
574
+ error: new Error(
575
+ `[@pactor-app/runtime] call \u5D4C\u5957\u8D85\u8FC7 ${MAX_CALL_DEPTH} \u5C42\uFF08\u7591\u4F3C\u5FAA\u73AF\u5F15\u7528\uFF09: "${name}"`
576
+ )
577
+ };
578
+ }
579
+ callDepth.set(ctx.context, depth);
580
+ try {
581
+ for (const child of asActions(target)) {
582
+ const result = await ctx.execute(child);
583
+ if (!result.ok) {
584
+ return result;
585
+ }
586
+ }
587
+ return { ok: true };
588
+ } finally {
589
+ callDepth.set(ctx.context, depth - 1);
590
+ }
591
+ });
449
592
  register("parallel", async (action, ctx) => {
450
593
  const results = await Promise.all(
451
594
  asActions(action.params?.["actions"]).map((child) => ctx.execute(child))
@@ -502,6 +645,8 @@ function asActions(value) {
502
645
  }
503
646
  return [];
504
647
  }
648
+ var callDepth = /* @__PURE__ */ new WeakMap();
649
+ var MAX_CALL_DEPTH = 20;
505
650
  function isRecord(value) {
506
651
  return typeof value === "object" && value !== null && !Array.isArray(value);
507
652
  }
@@ -557,7 +702,7 @@ var ActionEngine = class {
557
702
  // Renderer 的 resolveProps)保持原样,由各自执行/渲染时
558
703
  // 按当时的 state 与作用域求值
559
704
  params: resolveDeep(action.params ?? {}, scope, {
560
- isOpaque: (value) => typeof value["action"] === "string" || typeof value["type"] === "string"
705
+ isOpaque: (value) => typeof value["action"] === "string" || typeof value["type"] === "string" || typeof value["component"] === "string"
561
706
  })
562
707
  };
563
708
  const ctx = {
@@ -592,15 +737,57 @@ var ActionEngine = class {
592
737
  };
593
738
 
594
739
  // src/renderer/renderer.tsx
740
+ import { isDslSourceRef } from "@pactor-app/core";
595
741
  import {
596
742
  resolveTemplate as resolveTemplate3
597
743
  } from "@pactor-app/expression";
744
+ import { validateDslNode, validateDslNodes } from "@pactor-app/schema";
598
745
  import {
599
746
  createElement,
600
747
  useMemo,
601
748
  useSyncExternalStore as useSyncExternalStore2
602
749
  } from "react";
603
750
 
751
+ // src/renderer/dsl-source-boundary.tsx
752
+ import { useEffect, useState } from "react";
753
+ import { Fragment, jsx } from "react/jsx-runtime";
754
+ function DslSourceBoundary({
755
+ context,
756
+ sourceRef,
757
+ placeholder,
758
+ children
759
+ }) {
760
+ const [state, setState] = useState({ status: "loading" });
761
+ const key = dslSourceKey(sourceRef);
762
+ useEffect(() => {
763
+ let cancelled = false;
764
+ setState({ status: "loading" });
765
+ context.dslSources.resolve(sourceRef).then(
766
+ (content) => {
767
+ if (!cancelled) {
768
+ setState({ status: "ready", content });
769
+ }
770
+ },
771
+ (cause) => {
772
+ if (!cancelled) {
773
+ console.warn("[@pactor-app/runtime] DSL \u52A8\u6001\u5F15\u7528\u89E3\u6790\u5931\u8D25", cause);
774
+ setState({ status: "error" });
775
+ }
776
+ }
777
+ );
778
+ return () => {
779
+ cancelled = true;
780
+ };
781
+ }, [context, key]);
782
+ if (state.status === "ready") {
783
+ return /* @__PURE__ */ jsx(Fragment, { children: children(state.content) });
784
+ }
785
+ if (state.status === "error") {
786
+ return null;
787
+ }
788
+ return /* @__PURE__ */ jsx(Fragment, { children: placeholder ?? null });
789
+ }
790
+
604
791
  // src/renderer/renderer-context.ts
605
792
  import {
606
793
  createContext as createContext2,
@@ -654,7 +841,7 @@ function UnsupportedComponent({ type }) {
654
841
  }
655
842
 
656
843
  // src/renderer/renderer.tsx
657
- import { jsx, jsxs as jsxs2 } from "react/jsx-runtime";
844
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
658
845
  function DslRenderer({ context, node, engine, children }) {
659
846
  useSyncExternalStore2(
660
847
  (onChange) => {
@@ -676,6 +863,7 @@ function DslRenderer({ context, node, engine, children }) {
676
863
  context,
677
864
  engine: resolvedEngine,
678
865
  scope: {},
866
+ referenceStack: [],
679
867
  renderChildren: (children2, extraScope) => renderChildrenOf(root, children2, extraScope)
680
868
  };
681
869
  return root;
@@ -687,6 +875,44 @@ function DslRenderer({ context, node, engine, children }) {
687
875
  }
688
876
  function renderNode(node, value, key) {
689
877
  const scope = buildScope(value.context, value.scope);
878
+ if (node.component !== void 0) {
879
+ const name = node.component;
880
+ const stack = value.referenceStack ?? [];
881
+ if (stack.includes(name)) {
882
+ console.warn(
883
+ `[@pactor-app/runtime] \u7EC4\u4EF6\u5F15\u7528\u5FAA\u73AF\uFF1A${[...stack, name].join(" \u2192 ")}`
884
+ );
885
+ return null;
886
+ }
887
+ const subtree = value.context.pageComponents[name];
888
+ if (!subtree) {
889
+ return /* @__PURE__ */ jsx2(UnsupportedComponent, { type: `component(${name})` }, key);
890
+ }
891
+ const scoped = {
892
+ ...value,
893
+ referenceStack: [...stack, name]
894
+ };
895
+ scoped.renderChildren = (children, extraScope) => renderChildrenOf(scoped, children, extraScope);
896
+ if (isDslSourceRef(subtree)) {
897
+ const ref = subtree;
898
+ return /* @__PURE__ */ jsx2(RendererContextProvider, { value: scoped, children: /* @__PURE__ */ jsx2(
899
+ DslSourceBoundary,
900
+ {
901
+ context: value.context,
902
+ sourceRef: ref,
903
+ placeholder: ref.placeholder ? renderNode(ref.placeholder, scoped, "placeholder") : null,
904
+ children: (content) => {
905
+ const resolved = validateResolvedNode(content, `components.${name}`);
906
+ if (!resolved) {
907
+ return null;
908
+ }
909
+ return renderNode(mergeReferenceNode(resolved, node), scoped, key);
910
+ }
911
+ }
912
+ ) }, key);
913
+ }
914
+ return /* @__PURE__ */ jsx2(RendererContextProvider, { value: scoped, children: renderNode(mergeReferenceNode(subtree, node), scoped, key) }, key);
915
+ }
690
916
  if (node.when !== void 0) {
691
917
  const expression = typeof node.when === "string" ? node.when : node.when.expression;
692
918
  let visible;
@@ -713,7 +939,7 @@ function renderNode(node, value, key) {
713
939
  const entry = value.context.components.get(node.type);
714
940
  const normalized = normalizeEntry(entry);
715
941
  if (!normalized) {
716
- return /* @__PURE__ */ jsx(UnsupportedComponent, { type: node.type }, key);
942
+ return /* @__PURE__ */ jsx2(UnsupportedComponent, { type: node.type }, key);
717
943
  }
718
944
  const props = resolveProps(node.props, scope);
719
945
  if (node.events) {
@@ -747,23 +973,102 @@ function resolveDeniedStrategy(permission) {
747
973
  }
748
974
  return "hidden";
749
975
  }
976
+ function mergeReferenceNode(definition, reference) {
977
+ return {
978
+ ...definition,
979
+ props: { ...definition.props, ...reference.props },
980
+ events: { ...definition.events, ...reference.events },
981
+ when: reference.when ?? definition.when,
982
+ permission: reference.permission ?? definition.permission,
983
+ id: reference.id ?? definition.id
984
+ };
985
+ }
986
+ function validateResolvedNode(content, label) {
987
+ const errors = validateDslNode(content);
988
+ if (errors.length > 0) {
989
+ console.warn(
990
+ `[@pactor-app/runtime] \u52A8\u6001\u5F15\u7528\uFF08${label}\uFF09\u8FD4\u56DE\u5185\u5BB9\u672A\u901A\u8FC7\u6821\u9A8C`,
991
+ errors
992
+ );
993
+ return null;
994
+ }
995
+ return content;
996
+ }
997
+ function validateResolvedNodes(content, label) {
998
+ const errors = validateDslNodes(content);
999
+ if (errors.length > 0) {
1000
+ console.warn(
1001
+ `[@pactor-app/runtime] \u52A8\u6001\u5F15\u7528\uFF08${label}\uFF09\u8FD4\u56DE\u5185\u5BB9\u672A\u901A\u8FC7\u6821\u9A8C`,
1002
+ errors
1003
+ );
1004
+ return null;
1005
+ }
1006
+ return content;
1007
+ }
1008
+ function renderChildItem(value, item, key) {
1009
+ if (isDslSourceRef(item)) {
1010
+ const ref = item;
1011
+ return /* @__PURE__ */ jsx2(
1012
+ DslSourceBoundary,
1013
+ {
1014
+ context: value.context,
1015
+ sourceRef: ref,
1016
+ placeholder: ref.placeholder ? renderNode(ref.placeholder, value, "placeholder") : null,
1017
+ children: (content) => {
1018
+ const nodes = validateResolvedNodes(content, "children");
1019
+ if (!nodes) {
1020
+ return null;
1021
+ }
1022
+ return nodes.map(
1023
+ (child, index) => renderChildItem(value, child, isDslSourceRef(child) ? `ref-${index}` : child.id ?? index)
1024
+ );
1025
+ }
1026
+ },
1027
+ key
1028
+ );
1029
+ }
1030
+ return renderNode(item, value, key);
1031
+ }
750
1032
  function renderChildrenOf(value, children, extraScope) {
751
- if (!children || children.length === 0) {
1033
+ if (!children || Array.isArray(children) && children.length === 0) {
752
1034
  return null;
753
1035
  }
1036
+ if (isDslSourceRef(children)) {
1037
+ const ref = children;
1038
+ return /* @__PURE__ */ jsx2(
1039
+ DslSourceBoundary,
1040
+ {
1041
+ context: value.context,
1042
+ sourceRef: ref,
1043
+ placeholder: ref.placeholder ? renderNode(ref.placeholder, value, "placeholder") : null,
1044
+ children: (content) => {
1045
+ const nodes = validateResolvedNodes(content, "children");
1046
+ if (!nodes) {
1047
+ return null;
1048
+ }
1049
+ return nodes.map(
1050
+ (child, index) => renderChildItem(value, child, isDslSourceRef(child) ? `ref-${index}` : child.id ?? index)
1051
+ );
1052
+ }
1053
+ },
1054
+ "dsl-source"
1055
+ );
1056
+ }
1057
+ const itemKey = (child, index) => isDslSourceRef(child) ? `ref-${index}` : child.id ?? index;
754
1058
  if (!extraScope) {
755
1059
  return children.map(
756
- (child, index) => renderNode(child, value, child.id ?? index)
1060
+ (child, index) => renderChildItem(value, child, itemKey(child, index))
757
1061
  );
758
1062
  }
759
1063
  const scoped = {
760
1064
  context: value.context,
761
1065
  engine: value.engine,
762
1066
  scope: { ...value.scope, ...extraScope },
1067
+ referenceStack: value.referenceStack,
763
1068
  renderChildren: (nested, nestedScope) => renderChildrenOf(scoped, nested, nestedScope)
764
1069
  };
765
- return /* @__PURE__ */ jsx(RendererContextProvider, { value: scoped, children: children.map(
766
- (child, index) => renderNode(child, scoped, child.id ?? index)
1070
+ return /* @__PURE__ */ jsx2(RendererContextProvider, { value: scoped, children: children.map(
1071
+ (child, index) => renderChildItem(scoped, child, itemKey(child, index))
767
1072
  ) });
768
1073
  }
769
1074
  function normalizeEntry(entry) {
@@ -786,14 +1091,16 @@ function resolveProps(props, scope) {
786
1091
  return out;
787
1092
  }
788
1093
  function isEmbeddedDslNode(value) {
789
- return typeof value.type === "string";
1094
+ return typeof value.type === "string" || typeof value.component === "string";
790
1095
  }
791
1096
 
792
1097
  // src/page/page-runtime.tsx
1098
+ import { isDslSourceRef as isDslSourceRef2, resolveRootNodes } from "@pactor-app/core";
793
1099
  import {
1100
+ validateDslNodes as validateDslNodes2,
794
1101
  validatePageDsl
795
1102
  } from "@pactor-app/schema";
796
- import { Fragment, jsx as jsx2 } from "react/jsx-runtime";
1103
+ import { Fragment as Fragment2, jsx as jsx3 } from "react/jsx-runtime";
797
1104
  var PageRuntimeError = class extends Error {
798
1105
  constructor(errors) {
799
1106
  super(
@@ -812,7 +1119,9 @@ function createPageRuntime(pageDsl, options = {}) {
812
1119
  ...options,
813
1120
  page: pageDsl.page,
814
1121
  state: pageDsl.state ?? options.state,
815
- dataSources: pageDsl.dataSources ?? options.dataSources
1122
+ dataSources: pageDsl.dataSources ?? options.dataSources,
1123
+ namedActions: pageDsl.actions ?? options.namedActions,
1124
+ pageComponents: pageDsl.components ?? options.pageComponents
816
1125
  });
817
1126
  registerBuiltinActions(context.actions);
818
1127
  const engine = new ActionEngine(context);
@@ -848,10 +1157,7 @@ function createPageRuntime(pageDsl, options = {}) {
848
1157
  return destroyed;
849
1158
  },
850
1159
  render() {
851
- if (!pageDsl.body) {
852
- return null;
853
- }
854
- return /* @__PURE__ */ jsx2(DslRenderer, { context, node: pageDsl.body, engine });
1160
+ return renderRoots(pageDsl, context, engine);
855
1161
  },
856
1162
  ready: () => triggerWhenAlive("onReady"),
857
1163
  show: () => triggerWhenAlive("onShow"),
@@ -879,16 +1185,67 @@ function PageRuntimeView({
879
1185
  runtime,
880
1186
  children
881
1187
  }) {
882
- const body = runtime.pageDsl.body;
883
- if (!body) {
884
- return /* @__PURE__ */ jsx2(Fragment, { children: children ?? null });
1188
+ return renderRoots(runtime.pageDsl, runtime.context, runtime.engine, children);
1189
+ }
1190
+ function renderRoots(pageDsl, context, engine, children) {
1191
+ if (!pageDsl.body && isDslSourceRef2(pageDsl.children)) {
1192
+ const ref = pageDsl.children;
1193
+ return /* @__PURE__ */ jsx3(
1194
+ DslSourceBoundary,
1195
+ {
1196
+ context,
1197
+ sourceRef: ref,
1198
+ placeholder: ref.placeholder ? /* @__PURE__ */ jsx3(DslRenderer, { context, node: ref.placeholder, engine }) : null,
1199
+ children: (content) => renderResolvedRoots(content, context, engine, children)
1200
+ }
1201
+ );
1202
+ }
1203
+ const roots = resolveRootNodes(pageDsl);
1204
+ if (roots.length === 0) {
1205
+ return /* @__PURE__ */ jsx3(Fragment2, { children: children ?? null });
885
1206
  }
886
- return /* @__PURE__ */ jsx2(DslRenderer, { context: runtime.context, node: body, engine: runtime.engine, children });
1207
+ return renderRootItems(roots, context, engine, children);
1208
+ }
1209
+ function renderResolvedRoots(content, context, engine, children) {
1210
+ const errors = validateDslNodes2(content);
1211
+ if (errors.length > 0) {
1212
+ console.warn(
1213
+ "[@pactor-app/runtime] \u6839\u7EA7 children \u52A8\u6001\u5F15\u7528\u8FD4\u56DE\u5185\u5BB9\u672A\u901A\u8FC7\u6821\u9A8C",
1214
+ errors
1215
+ );
1216
+ return /* @__PURE__ */ jsx3(Fragment2, { children: children ?? null });
1217
+ }
1218
+ return renderRootItems(content, context, engine, children);
1219
+ }
1220
+ function renderRootItems(items, context, engine, children) {
1221
+ return /* @__PURE__ */ jsx3(Fragment2, { children: items.map(
1222
+ (item, index) => isDslSourceRef2(item) ? /* @__PURE__ */ jsx3(
1223
+ DslSourceBoundary,
1224
+ {
1225
+ context,
1226
+ sourceRef: item,
1227
+ placeholder: item.placeholder ? /* @__PURE__ */ jsx3(DslRenderer, { context, node: item.placeholder, engine }) : null,
1228
+ children: (content) => renderResolvedRoots(content, context, engine, children)
1229
+ },
1230
+ dslSourceKey(item)
1231
+ ) : /* @__PURE__ */ jsx3(
1232
+ DslRenderer,
1233
+ {
1234
+ context,
1235
+ node: item,
1236
+ engine,
1237
+ children: index === items.length - 1 ? children : null
1238
+ },
1239
+ item.id ?? index
1240
+ )
1241
+ ) });
887
1242
  }
888
1243
  export {
889
1244
  ActionEngine,
890
1245
  DataStore,
891
1246
  DslRenderer,
1247
+ DslSourceBoundary,
1248
+ DslSourceResolver,
892
1249
  I18nContextProvider,
893
1250
  PageRuntimeError,
894
1251
  PageRuntimeView,
@@ -900,6 +1257,7 @@ export {
900
1257
  createFetchHttpAdapter,
901
1258
  createPageRuntime,
902
1259
  createRuntimeContext,
1260
+ dslSourceKey,
903
1261
  registerBuiltinActions,
904
1262
  resolveDeep,
905
1263
  useDataSource,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pactor-app/runtime",
3
- "version": "0.1.0",
3
+ "version": "1.0.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": "0.1.0",
49
- "@pactor-app/expression": "0.1.0",
50
- "@pactor-app/schema": "0.1.0"
48
+ "@pactor-app/core": "1.0.0",
49
+ "@pactor-app/expression": "1.0.0",
50
+ "@pactor-app/schema": "1.0.0"
51
51
  },
52
52
  "peerDependencies": {
53
53
  "react": ">=18"