@cratis/scene.engine 4.13.0 → 4.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.
Files changed (67) hide show
  1. package/QueryBindingState.ts +43 -0
  2. package/QueryBindingTicket.ts +8 -0
  3. package/dist/cjs/QueryBindingState.js +38 -0
  4. package/dist/cjs/QueryBindingState.js.map +1 -0
  5. package/dist/cjs/forms/CommandFormLayoutKey.js +14 -0
  6. package/dist/cjs/forms/CommandFormLayoutKey.js.map +1 -0
  7. package/dist/cjs/forms/applyCommandFormLayoutKey.js +72 -0
  8. package/dist/cjs/forms/applyCommandFormLayoutKey.js.map +1 -0
  9. package/dist/cjs/forms/stackCommandFormLayout.js +37 -0
  10. package/dist/cjs/forms/stackCommandFormLayout.js.map +1 -0
  11. package/dist/cjs/index.js +12 -0
  12. package/dist/cjs/index.js.map +1 -1
  13. package/dist/cjs/nestBindingScope.js +26 -0
  14. package/dist/cjs/nestBindingScope.js.map +1 -0
  15. package/dist/cjs/removeComponentOutputs.js +19 -0
  16. package/dist/cjs/removeComponentOutputs.js.map +1 -0
  17. package/dist/cjs/resolveBindingExpression.js +12 -8
  18. package/dist/cjs/resolveBindingExpression.js.map +1 -1
  19. package/dist/esm/QueryBindingState.d.ts +10 -0
  20. package/dist/esm/QueryBindingState.d.ts.map +1 -0
  21. package/dist/esm/QueryBindingState.js +36 -0
  22. package/dist/esm/QueryBindingState.js.map +1 -0
  23. package/dist/esm/QueryBindingTicket.d.ts +5 -0
  24. package/dist/esm/QueryBindingTicket.d.ts.map +1 -0
  25. package/dist/esm/QueryBindingTicket.js +2 -0
  26. package/dist/esm/QueryBindingTicket.js.map +1 -0
  27. package/dist/esm/forms/CommandFormLayoutKey.d.ts +7 -0
  28. package/dist/esm/forms/CommandFormLayoutKey.d.ts.map +1 -0
  29. package/dist/esm/forms/CommandFormLayoutKey.js +12 -0
  30. package/dist/esm/forms/CommandFormLayoutKey.js.map +1 -0
  31. package/dist/esm/forms/applyCommandFormLayoutKey.d.ts +5 -0
  32. package/dist/esm/forms/applyCommandFormLayoutKey.d.ts.map +1 -0
  33. package/dist/esm/forms/applyCommandFormLayoutKey.js +70 -0
  34. package/dist/esm/forms/applyCommandFormLayoutKey.js.map +1 -0
  35. package/dist/esm/forms/index.d.ts +3 -0
  36. package/dist/esm/forms/index.d.ts.map +1 -1
  37. package/dist/esm/forms/index.js +3 -0
  38. package/dist/esm/forms/index.js.map +1 -1
  39. package/dist/esm/forms/stackCommandFormLayout.d.ts +3 -0
  40. package/dist/esm/forms/stackCommandFormLayout.d.ts.map +1 -0
  41. package/dist/esm/forms/stackCommandFormLayout.js +35 -0
  42. package/dist/esm/forms/stackCommandFormLayout.js.map +1 -0
  43. package/dist/esm/index.d.ts +4 -0
  44. package/dist/esm/index.d.ts.map +1 -1
  45. package/dist/esm/index.js +6 -0
  46. package/dist/esm/index.js.map +1 -1
  47. package/dist/esm/nestBindingScope.d.ts +3 -0
  48. package/dist/esm/nestBindingScope.d.ts.map +1 -0
  49. package/dist/esm/nestBindingScope.js +24 -0
  50. package/dist/esm/nestBindingScope.js.map +1 -0
  51. package/dist/esm/removeComponentOutputs.d.ts +3 -0
  52. package/dist/esm/removeComponentOutputs.d.ts.map +1 -0
  53. package/dist/esm/removeComponentOutputs.js +17 -0
  54. package/dist/esm/removeComponentOutputs.js.map +1 -0
  55. package/dist/esm/resolveBindingExpression.d.ts.map +1 -1
  56. package/dist/esm/resolveBindingExpression.js +12 -8
  57. package/dist/esm/resolveBindingExpression.js.map +1 -1
  58. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  59. package/forms/CommandFormLayoutKey.ts +10 -0
  60. package/forms/applyCommandFormLayoutKey.ts +47 -0
  61. package/forms/index.ts +3 -0
  62. package/forms/stackCommandFormLayout.ts +22 -0
  63. package/index.ts +4 -0
  64. package/nestBindingScope.ts +19 -0
  65. package/package.json +3 -3
  66. package/removeComponentOutputs.ts +15 -0
  67. package/resolveBindingExpression.ts +14 -7
@@ -0,0 +1,70 @@
1
+ import { CommandFormLayoutKey } from './CommandFormLayoutKey.js';
2
+ import { updateCommandFormFieldPlacement } from './updateCommandFormFieldPlacement.js';
3
+
4
+ // Copyright (c) Cratis. All rights reserved.
5
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
6
+ /**
7
+ * Moves or resizes one field from the keyboard, so the layout can be arranged without a pointer.
8
+ *
9
+ * An arrow key moves the field one cell; with `resize`, Left and Right narrow and widen its column span and
10
+ * Up and Down shorten and lengthen its row span. Positions are one-based and never go below one, and spans never below one.
11
+ * The result is a draft validated like any other placement change, so a move or resize past the last
12
+ * column is reported in its diagnostics and the committed layout is kept. Returns undefined for a field that is not placed.
13
+ */ function applyCommandFormLayoutKey(committed, field, key, resize = false, fields = []) {
14
+ const placement = committed.placements.find((candidate)=>candidate.field === field);
15
+ if (!placement) return undefined;
16
+ return updateCommandFormFieldPlacement(committed, resize ? resized(placement, key) : moved(placement, key), fields);
17
+ }
18
+ function moved(placement, key) {
19
+ switch(key){
20
+ case CommandFormLayoutKey.ArrowLeft:
21
+ return {
22
+ ...placement,
23
+ column: Math.max(1, placement.column - 1)
24
+ };
25
+ case CommandFormLayoutKey.ArrowRight:
26
+ return {
27
+ ...placement,
28
+ column: placement.column + 1
29
+ };
30
+ case CommandFormLayoutKey.ArrowUp:
31
+ return {
32
+ ...placement,
33
+ row: Math.max(1, placement.row - 1)
34
+ };
35
+ case CommandFormLayoutKey.ArrowDown:
36
+ return {
37
+ ...placement,
38
+ row: placement.row + 1
39
+ };
40
+ }
41
+ }
42
+ function resized(placement, key) {
43
+ const columnSpan = placement.columnSpan ?? 1;
44
+ const rowSpan = placement.rowSpan ?? 1;
45
+ switch(key){
46
+ case CommandFormLayoutKey.ArrowLeft:
47
+ return {
48
+ ...placement,
49
+ columnSpan: Math.max(1, columnSpan - 1)
50
+ };
51
+ case CommandFormLayoutKey.ArrowRight:
52
+ return {
53
+ ...placement,
54
+ columnSpan: columnSpan + 1
55
+ };
56
+ case CommandFormLayoutKey.ArrowUp:
57
+ return {
58
+ ...placement,
59
+ rowSpan: Math.max(1, rowSpan - 1)
60
+ };
61
+ case CommandFormLayoutKey.ArrowDown:
62
+ return {
63
+ ...placement,
64
+ rowSpan: rowSpan + 1
65
+ };
66
+ }
67
+ }
68
+
69
+ export { applyCommandFormLayoutKey };
70
+ //# sourceMappingURL=applyCommandFormLayoutKey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"applyCommandFormLayoutKey.js","sources":["../../../forms/applyCommandFormLayoutKey.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { CommandFormLayout, FormFieldPlacement } from '@cratis/scene.model';\nimport { CommandFormLayoutDraft } from './CommandFormLayoutDraft';\nimport { CommandFormLayoutKey } from './CommandFormLayoutKey';\nimport { updateCommandFormFieldPlacement } from './updateCommandFormFieldPlacement';\n\n/**\n * Moves or resizes one field from the keyboard, so the layout can be arranged without a pointer.\n *\n * An arrow key moves the field one cell; with `resize`, Left and Right narrow and widen its column span and\n * Up and Down shorten and lengthen its row span. Positions are one-based and never go below one, and spans never below one.\n * The result is a draft validated like any other placement change, so a move or resize past the last\n * column is reported in its diagnostics and the committed layout is kept. Returns undefined for a field that is not placed.\n */\nexport function applyCommandFormLayoutKey(\n committed: CommandFormLayout,\n field: string,\n key: CommandFormLayoutKey,\n resize = false,\n fields: readonly string[] = [],\n): CommandFormLayoutDraft | undefined {\n const placement = committed.placements.find(candidate => candidate.field === field);\n if (!placement) return undefined;\n return updateCommandFormFieldPlacement(committed, resize ? resized(placement, key) : moved(placement, key), fields);\n}\n\nfunction moved(placement: FormFieldPlacement, key: CommandFormLayoutKey): FormFieldPlacement {\n switch (key) {\n case CommandFormLayoutKey.ArrowLeft: return { ...placement, column: Math.max(1, placement.column - 1) };\n case CommandFormLayoutKey.ArrowRight: return { ...placement, column: placement.column + 1 };\n case CommandFormLayoutKey.ArrowUp: return { ...placement, row: Math.max(1, placement.row - 1) };\n case CommandFormLayoutKey.ArrowDown: return { ...placement, row: placement.row + 1 };\n }\n}\n\nfunction resized(placement: FormFieldPlacement, key: CommandFormLayoutKey): FormFieldPlacement {\n const columnSpan = placement.columnSpan ?? 1;\n const rowSpan = placement.rowSpan ?? 1;\n switch (key) {\n case CommandFormLayoutKey.ArrowLeft: return { ...placement, columnSpan: Math.max(1, columnSpan - 1) };\n case CommandFormLayoutKey.ArrowRight: return { ...placement, columnSpan: columnSpan + 1 };\n case CommandFormLayoutKey.ArrowUp: return { ...placement, rowSpan: Math.max(1, rowSpan - 1) };\n case CommandFormLayoutKey.ArrowDown: return { ...placement, rowSpan: rowSpan + 1 };\n }\n}\n"],"names":["applyCommandFormLayoutKey","committed","field","key","resize","fields","placement","placements","find","candidate","undefined","updateCommandFormFieldPlacement","resized","moved","CommandFormLayoutKey","ArrowLeft","column","Math","max","ArrowRight","ArrowUp","row","ArrowDown","columnSpan","rowSpan"],"mappings":";;;AAAA;AACA;AAOA;;;;;;;AAOC,IACM,SAASA,yBAAAA,CACZC,SAA4B,EAC5BC,KAAa,EACbC,GAAyB,EACzBC,MAAAA,GAAS,KAAK,EACdC,SAA4B,EAAE,EAAA;IAE9B,MAAMC,SAAAA,GAAYL,SAAAA,CAAUM,UAAU,CAACC,IAAI,CAACC,CAAAA,SAAAA,GAAaA,SAAAA,CAAUP,KAAK,KAAKA,KAAAA,CAAAA;IAC7E,IAAI,CAACI,WAAW,OAAOI,SAAAA;IACvB,OAAOC,+BAAAA,CAAgCV,WAAWG,MAAAA,GAASQ,OAAAA,CAAQN,WAAWH,GAAAA,CAAAA,GAAOU,KAAAA,CAAMP,WAAWH,GAAAA,CAAAA,EAAME,MAAAA,CAAAA;AAChH;AAEA,SAASQ,KAAAA,CAAMP,SAA6B,EAAEH,GAAyB,EAAA;IACnE,OAAQA,GAAAA;AACJ,QAAA,KAAKW,qBAAqBC,SAAS;YAAE,OAAO;AAAE,gBAAA,GAAGT,SAAS;AAAEU,gBAAAA,MAAAA,EAAQC,KAAKC,GAAG,CAAC,CAAA,EAAGZ,SAAAA,CAAUU,MAAM,GAAG,CAAA;AAAG,aAAA;AACtG,QAAA,KAAKF,qBAAqBK,UAAU;YAAE,OAAO;AAAE,gBAAA,GAAGb,SAAS;gBAAEU,MAAAA,EAAQV,SAAAA,CAAUU,MAAM,GAAG;AAAE,aAAA;AAC1F,QAAA,KAAKF,qBAAqBM,OAAO;YAAE,OAAO;AAAE,gBAAA,GAAGd,SAAS;AAAEe,gBAAAA,GAAAA,EAAKJ,KAAKC,GAAG,CAAC,CAAA,EAAGZ,SAAAA,CAAUe,GAAG,GAAG,CAAA;AAAG,aAAA;AAC9F,QAAA,KAAKP,qBAAqBQ,SAAS;YAAE,OAAO;AAAE,gBAAA,GAAGhB,SAAS;gBAAEe,GAAAA,EAAKf,SAAAA,CAAUe,GAAG,GAAG;AAAE,aAAA;AACvF;AACJ;AAEA,SAAST,OAAAA,CAAQN,SAA6B,EAAEH,GAAyB,EAAA;IACrE,MAAMoB,UAAAA,GAAajB,SAAAA,CAAUiB,UAAU,IAAI,CAAA;IAC3C,MAAMC,OAAAA,GAAUlB,SAAAA,CAAUkB,OAAO,IAAI,CAAA;IACrC,OAAQrB,GAAAA;AACJ,QAAA,KAAKW,qBAAqBC,SAAS;YAAE,OAAO;AAAE,gBAAA,GAAGT,SAAS;AAAEiB,gBAAAA,UAAAA,EAAYN,IAAAA,CAAKC,GAAG,CAAC,CAAA,EAAGK,UAAAA,GAAa,CAAA;AAAG,aAAA;AACpG,QAAA,KAAKT,qBAAqBK,UAAU;YAAE,OAAO;AAAE,gBAAA,GAAGb,SAAS;AAAEiB,gBAAAA,UAAAA,EAAYA,UAAAA,GAAa;AAAE,aAAA;AACxF,QAAA,KAAKT,qBAAqBM,OAAO;YAAE,OAAO;AAAE,gBAAA,GAAGd,SAAS;AAAEkB,gBAAAA,OAAAA,EAASP,IAAAA,CAAKC,GAAG,CAAC,CAAA,EAAGM,OAAAA,GAAU,CAAA;AAAG,aAAA;AAC5F,QAAA,KAAKV,qBAAqBQ,SAAS;YAAE,OAAO;AAAE,gBAAA,GAAGhB,SAAS;AAAEkB,gBAAAA,OAAAA,EAASA,OAAAA,GAAU;AAAE,aAAA;AACrF;AACJ;;"}
@@ -10,4 +10,7 @@ export * from './preserveDirtyCommandValues';
10
10
  export * from './resizeCommandFormColumn';
11
11
  export * from './updateCommandFormFieldPlacement';
12
12
  export * from './validateCommandFormLayout';
13
+ export * from './CommandFormLayoutKey';
14
+ export * from './applyCommandFormLayoutKey';
15
+ export * from './stackCommandFormLayout';
13
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../forms/index.ts"],"names":[],"mappings":"AAGA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mCAAmC,CAAC;AAClD,cAAc,0BAA0B,CAAC;AACzC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kBAAkB,CAAC;AACjC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kBAAkB,CAAC;AACjC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../forms/index.ts"],"names":[],"mappings":"AAGA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mCAAmC,CAAC;AAClD,cAAc,0BAA0B,CAAC;AACzC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kBAAkB,CAAC;AACjC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kBAAkB,CAAC;AACjC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC"}
@@ -10,4 +10,7 @@ export * from './preserveDirtyCommandValues';
10
10
  export * from './resizeCommandFormColumn';
11
11
  export * from './updateCommandFormFieldPlacement';
12
12
  export * from './validateCommandFormLayout';
13
+ export * from './CommandFormLayoutKey';
14
+ export * from './applyCommandFormLayoutKey';
15
+ export * from './stackCommandFormLayout';
13
16
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../forms/index.ts"],"names":[],"mappings":"AAGA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mCAAmC,CAAC;AAClD,cAAc,0BAA0B,CAAC;AACzC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kBAAkB,CAAC;AACjC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kBAAkB,CAAC;AACjC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../forms/index.ts"],"names":[],"mappings":"AAGA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mCAAmC,CAAC;AAClD,cAAc,0BAA0B,CAAC;AACzC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kBAAkB,CAAC;AACjC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kBAAkB,CAAC;AACjC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { CommandFormLayout } from '@cratis/scene.model';
2
+ export declare function stackCommandFormLayout(layout: CommandFormLayout): CommandFormLayout;
3
+ //# sourceMappingURL=stackCommandFormLayout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stackCommandFormLayout.d.ts","sourceRoot":"","sources":["../../../forms/stackCommandFormLayout.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAiB,MAAM,qBAAqB,CAAC;AAQvE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,iBAAiB,GAAG,iBAAiB,CAUnF"}
@@ -0,0 +1,35 @@
1
+ import { FormWidthUnit } from '@cratis/scene.model';
2
+
3
+ // Copyright (c) Cratis. All rights reserved.
4
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
5
+ /**
6
+ * The layout a command form uses at a compact width: one full-width column, every field on its own row,
7
+ * in reading order - row first, then column, then authored order. Spans and per-field widths are dropped
8
+ * because there is nothing to span. The authored layout is not changed, so the form returns to its columns
9
+ * at a regular width.
10
+ */ function stackCommandFormLayout(layout) {
11
+ const ordered = layout.placements.map((placement, order)=>({
12
+ placement,
13
+ order
14
+ })).sort((left, right)=>left.placement.row - right.placement.row || left.placement.column - right.placement.column || left.order - right.order);
15
+ return {
16
+ ...layout,
17
+ columns: [
18
+ {
19
+ index: 1,
20
+ width: {
21
+ unit: FormWidthUnit.Fraction,
22
+ value: 1
23
+ }
24
+ }
25
+ ],
26
+ placements: ordered.map(({ placement }, index)=>({
27
+ field: placement.field,
28
+ row: index + 1,
29
+ column: 1
30
+ }))
31
+ };
32
+ }
33
+
34
+ export { stackCommandFormLayout };
35
+ //# sourceMappingURL=stackCommandFormLayout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stackCommandFormLayout.js","sources":["../../../forms/stackCommandFormLayout.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { CommandFormLayout, FormWidthUnit } from '@cratis/scene.model';\n\n/**\n * The layout a command form uses at a compact width: one full-width column, every field on its own row,\n * in reading order - row first, then column, then authored order. Spans and per-field widths are dropped\n * because there is nothing to span. The authored layout is not changed, so the form returns to its columns\n * at a regular width.\n */\nexport function stackCommandFormLayout(layout: CommandFormLayout): CommandFormLayout {\n const ordered = layout.placements\n .map((placement, order) => ({ placement, order }))\n .sort((left, right) => left.placement.row - right.placement.row || left.placement.column - right.placement.column || left.order - right.order);\n\n return {\n ...layout,\n columns: [{ index: 1, width: { unit: FormWidthUnit.Fraction, value: 1 } }],\n placements: ordered.map(({ placement }, index) => ({ field: placement.field, row: index + 1, column: 1 })),\n };\n}\n"],"names":["stackCommandFormLayout","layout","ordered","placements","map","placement","order","sort","left","right","row","column","columns","index","width","unit","FormWidthUnit","Fraction","value","field"],"mappings":";;AAAA;AACA;AAIA;;;;;IAMO,SAASA,sBAAAA,CAAuBC,MAAyB,EAAA;IAC5D,MAAMC,OAAAA,GAAUD,OAAOE,UAAU,CAC5BC,GAAG,CAAC,CAACC,SAAAA,EAAWC,KAAAA,IAAW;AAAED,YAAAA,SAAAA;AAAWC,YAAAA;AAAM,SAAA,CAAA,CAAA,CAC9CC,IAAI,CAAC,CAACC,IAAAA,EAAMC,KAAAA,GAAUD,IAAAA,CAAKH,SAAS,CAACK,GAAG,GAAGD,KAAAA,CAAMJ,SAAS,CAACK,GAAG,IAAIF,IAAAA,CAAKH,SAAS,CAACM,MAAM,GAAGF,KAAAA,CAAMJ,SAAS,CAACM,MAAM,IAAIH,IAAAA,CAAKF,KAAK,GAAGG,MAAMH,KAAK,CAAA;IAEjJ,OAAO;AACH,QAAA,GAAGL,MAAM;QACTW,OAAAA,EAAS;AAAC,YAAA;gBAAEC,KAAAA,EAAO,CAAA;gBAAGC,KAAAA,EAAO;AAAEC,oBAAAA,IAAAA,EAAMC,cAAcC,QAAQ;oBAAEC,KAAAA,EAAO;AAAE;AAAE;AAAE,SAAA;QAC1Ef,UAAAA,EAAYD,OAAAA,CAAQE,GAAG,CAAC,CAAC,EAAEC,SAAS,EAAE,EAAEQ,KAAAA,IAAW;AAAEM,gBAAAA,KAAAA,EAAOd,UAAUc,KAAK;AAAET,gBAAAA,GAAAA,EAAKG,KAAAA,GAAQ,CAAA;gBAAGF,MAAAA,EAAQ;aAAE,CAAA;AAC3G,KAAA;AACJ;;"}
@@ -3,6 +3,10 @@ export * from './BindingResolver';
3
3
  export * from './BindingScope';
4
4
  export * from './BindingDiagnostic';
5
5
  export * from './resolveBindingExpression';
6
+ export * from './nestBindingScope';
7
+ export * from './removeComponentOutputs';
8
+ export * from './QueryBindingState';
9
+ export * from './QueryBindingTicket';
6
10
  export * from './validateBindingExpression';
7
11
  export * from './renderElement';
8
12
  export * from './forms';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../index.ts"],"names":[],"mappings":"AAGA,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iBAAiB,CAAC;AAChC,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,SAAS,CAAC;AACxB,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mCAAmC,CAAC;AAClD,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,kCAAkC,CAAC;AACjD,cAAc,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../index.ts"],"names":[],"mappings":"AAGA,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iBAAiB,CAAC;AAChC,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,SAAS,CAAC;AACxB,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mCAAmC,CAAC;AAClD,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,kCAAkC,CAAC;AACjD,cAAc,WAAW,CAAC"}
package/dist/esm/index.js CHANGED
@@ -1,4 +1,7 @@
1
1
  export { createBindingResolver, resolveBindingExpression } from './resolveBindingExpression.js';
2
+ export { nestBindingScope } from './nestBindingScope.js';
3
+ export { removeComponentOutputs } from './removeComponentOutputs.js';
4
+ export { QueryBindingState } from './QueryBindingState.js';
2
5
  export { validateBindingExpression } from './validateBindingExpression.js';
3
6
  export { renderElement } from './renderElement.js';
4
7
  export { CommandFormLayoutDiagnosticCode } from './forms/CommandFormLayoutDiagnosticCode.js';
@@ -11,6 +14,9 @@ export { preserveDirtyCommandValues } from './forms/preserveDirtyCommandValues.j
11
14
  export { resizeCommandFormColumn } from './forms/resizeCommandFormColumn.js';
12
15
  export { updateCommandFormFieldPlacement } from './forms/updateCommandFormFieldPlacement.js';
13
16
  export { validateCommandFormLayout } from './forms/validateCommandFormLayout.js';
17
+ export { CommandFormLayoutKey } from './forms/CommandFormLayoutKey.js';
18
+ export { applyCommandFormLayoutKey } from './forms/applyCommandFormLayoutKey.js';
19
+ export { stackCommandFormLayout } from './forms/stackCommandFormLayout.js';
14
20
  export { isContentControl, isExternalComponent, isItemsControl, isPanel } from './elementKind.js';
15
21
  export { isCanvas, isDockPanel, isGrid, isStackPanel, isWrapPanel } from './panelKind.js';
16
22
  export { isFlowColumn, isFlowContainer, isFlowGrid, isFlowLeaf, isFlowRow, isFlowSlotLeaf } from './flowNodeKind.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,3 @@
1
+ import { BindingScope } from './BindingScope';
2
+ export declare function nestBindingScope(parent: BindingScope, nested: BindingScope): BindingScope;
3
+ //# sourceMappingURL=nestBindingScope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nestBindingScope.d.ts","sourceRoot":"","sources":["../../nestBindingScope.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAS9C,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,GAAG,YAAY,CAMzF"}
@@ -0,0 +1,24 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+ /**
4
+ * The scope a nested template or region sees. A data context it declares replaces the inherited one - a
5
+ * detail region bound to the selected row reads that row, not the screen's - while query results and
6
+ * component outputs are inherited, with its own entries shadowing the parent's of the same name. A null
7
+ * data context inherits, as in the C# engine, which cannot tell null from absent. The parent scope is not
8
+ * changed.
9
+ */ function nestBindingScope(parent, nested) {
10
+ return {
11
+ dataContext: nested.dataContext ?? parent.dataContext,
12
+ queryResults: {
13
+ ...parent.queryResults ?? {},
14
+ ...nested.queryResults ?? {}
15
+ },
16
+ componentOutputs: {
17
+ ...parent.componentOutputs ?? {},
18
+ ...nested.componentOutputs ?? {}
19
+ }
20
+ };
21
+ }
22
+
23
+ export { nestBindingScope };
24
+ //# sourceMappingURL=nestBindingScope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nestBindingScope.js","sources":["../../nestBindingScope.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { BindingScope } from './BindingScope';\n\n/**\n * The scope a nested template or region sees. A data context it declares replaces the inherited one - a\n * detail region bound to the selected row reads that row, not the screen's - while query results and\n * component outputs are inherited, with its own entries shadowing the parent's of the same name. A null\n * data context inherits, as in the C# engine, which cannot tell null from absent. The parent scope is not\n * changed.\n */\nexport function nestBindingScope(parent: BindingScope, nested: BindingScope): BindingScope {\n return {\n dataContext: nested.dataContext ?? parent.dataContext,\n queryResults: { ...(parent.queryResults ?? {}), ...(nested.queryResults ?? {}) },\n componentOutputs: { ...(parent.componentOutputs ?? {}), ...(nested.componentOutputs ?? {}) },\n };\n}\n"],"names":["nestBindingScope","parent","nested","dataContext","queryResults","componentOutputs"],"mappings":"AAAA;AACA;AAIA;;;;;;AAMC,IACM,SAASA,gBAAAA,CAAiBC,MAAoB,EAAEC,MAAoB,EAAA;IACvE,OAAO;AACHC,QAAAA,WAAAA,EAAaD,MAAAA,CAAOC,WAAW,IAAIF,MAAAA,CAAOE,WAAW;QACrDC,YAAAA,EAAc;AAAE,YAAA,GAAIH,MAAAA,CAAOG,YAAY,IAAI,EAAE;AAAG,YAAA,GAAIF,MAAAA,CAAOE,YAAY,IAAI;AAAI,SAAA;QAC/EC,gBAAAA,EAAkB;AAAE,YAAA,GAAIJ,MAAAA,CAAOI,gBAAgB,IAAI,EAAE;AAAG,YAAA,GAAIH,MAAAA,CAAOG,gBAAgB,IAAI;AAAI;AAC/F,KAAA;AACJ;;"}
@@ -0,0 +1,3 @@
1
+ import { BindingScope } from './BindingScope';
2
+ export declare function removeComponentOutputs(scope: BindingScope, elementIds: string[]): BindingScope;
3
+ //# sourceMappingURL=removeComponentOutputs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"removeComponentOutputs.d.ts","sourceRoot":"","sources":["../../removeComponentOutputs.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAO9C,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,YAAY,CAI9F"}
@@ -0,0 +1,17 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+ /**
4
+ * The scope after elements leave the tree - unmounted, deleted or renamed to a new id. Their output
5
+ * properties are removed, so a binding to them resolves as absent and validates as `unknownComponent`
6
+ * instead of reading a value from an element that no longer exists.
7
+ */ function removeComponentOutputs(scope, elementIds) {
8
+ const removed = new Set(elementIds);
9
+ const componentOutputs = Object.fromEntries(Object.entries(scope.componentOutputs ?? {}).filter(([id])=>!removed.has(id)));
10
+ return {
11
+ ...scope,
12
+ componentOutputs
13
+ };
14
+ }
15
+
16
+ export { removeComponentOutputs };
17
+ //# sourceMappingURL=removeComponentOutputs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"removeComponentOutputs.js","sources":["../../removeComponentOutputs.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { BindingScope } from './BindingScope';\n\n/**\n * The scope after elements leave the tree - unmounted, deleted or renamed to a new id. Their output\n * properties are removed, so a binding to them resolves as absent and validates as `unknownComponent`\n * instead of reading a value from an element that no longer exists.\n */\nexport function removeComponentOutputs(scope: BindingScope, elementIds: string[]): BindingScope {\n const removed = new Set(elementIds);\n const componentOutputs = Object.fromEntries(Object.entries(scope.componentOutputs ?? {}).filter(([id]) => !removed.has(id)));\n return { ...scope, componentOutputs };\n}\n"],"names":["removeComponentOutputs","scope","elementIds","removed","Set","componentOutputs","Object","fromEntries","entries","filter","id","has"],"mappings":"AAAA;AACA;AAIA;;;;AAIC,IACM,SAASA,sBAAAA,CAAuBC,KAAmB,EAAEC,UAAoB,EAAA;IAC5E,MAAMC,OAAAA,GAAU,IAAIC,GAAAA,CAAIF,UAAAA,CAAAA;IACxB,MAAMG,gBAAAA,GAAmBC,OAAOC,WAAW,CAACD,OAAOE,OAAO,CAACP,MAAMI,gBAAgB,IAAI,EAAC,CAAA,CAAGI,MAAM,CAAC,CAAC,CAACC,GAAG,GAAK,CAACP,OAAAA,CAAQQ,GAAG,CAACD,EAAAA,CAAAA,CAAAA,CAAAA;IACvH,OAAO;AAAE,QAAA,GAAGT,KAAK;AAAEI,QAAAA;AAAiB,KAAA;AACxC;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"resolveBindingExpression.d.ts","sourceRoot":"","sources":["../../resolveBindingExpression.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAA0C,MAAM,qBAAqB,CAAC;AAChG,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAK9C,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAWjG;AAKD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,YAAY,GAAG,CAAC,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAElG"}
1
+ {"version":3,"file":"resolveBindingExpression.d.ts","sourceRoot":"","sources":["../../resolveBindingExpression.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAA0C,MAAM,qBAAqB,CAAC;AAChG,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAK9C,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAajG;AAKD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,YAAY,GAAG,CAAC,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAElG"}
@@ -6,9 +6,9 @@ import { BindingSourceKind, BindingNullBehavior } from '@cratis/scene.model';
6
6
  * Resolves a typed binding against the shared runtime binding scope.
7
7
  */ function resolveBindingExpression(binding, scope) {
8
8
  const kind = binding.kind ?? BindingSourceKind.DataContext;
9
- if (kind === BindingSourceKind.Literal) return binding.value;
10
- const source = sourceValue(binding, scope, kind);
11
- const value = readPath(source, sourcePath(binding, kind));
9
+ // A literal without a value is absent, whether the author wrote `null` or nothing: the C# model cannot
10
+ // tell the two apart, and both engines must resolve the same document to the same value.
11
+ const value = kind === BindingSourceKind.Literal ? binding.value ?? undefined : readPath(sourceValue(binding, scope, kind), sourcePath(binding, kind));
12
12
  if (value !== null && value !== undefined) return value;
13
13
  if (binding.nullBehavior === BindingNullBehavior.Preserve) return undefined;
14
14
  if (binding.nullBehavior === BindingNullBehavior.Clear) return null;
@@ -22,7 +22,7 @@ import { BindingSourceKind, BindingNullBehavior } from '@cratis/scene.model';
22
22
  function sourceValue(binding, scope, kind) {
23
23
  switch(kind){
24
24
  case BindingSourceKind.DataContext:
25
- return scope.dataContext;
25
+ return scope.dataContext ?? undefined;
26
26
  case BindingSourceKind.QueryResult:
27
27
  return binding.query ? scope.queryResults?.[binding.query] : undefined;
28
28
  case BindingSourceKind.ComponentProperty:
@@ -35,12 +35,16 @@ function sourcePath(binding, kind) {
35
35
  if (kind === BindingSourceKind.ComponentProperty) return binding.componentPropertyPath ?? binding.path;
36
36
  return binding.path;
37
37
  }
38
- function readPath(source, path) {
38
+ /**
39
+ * Reads a dotted path. Only own properties and array indexes are read - never inherited members such as
40
+ * `constructor` - and anything that is not an object or array ends the walk, so the C# engine can follow
41
+ * exactly the same rule over JSON.
42
+ */ function readPath(source, path) {
39
43
  if (!path) return source;
40
44
  return path.split('.').reduce((current, segment)=>{
41
- if (current === null || current === undefined) return undefined;
42
- if (typeof current !== 'object') return undefined;
43
- return current[segment];
45
+ if (current === null || current === undefined || typeof current !== 'object') return undefined;
46
+ if (Array.isArray(current)) return /^(0|[1-9][0-9]*)$/.test(segment) ? current[Number(segment)] : undefined;
47
+ return Object.hasOwn(current, segment) ? current[segment] : undefined;
44
48
  }, source);
45
49
  }
46
50
 
@@ -1 +1 @@
1
- {"version":3,"file":"resolveBindingExpression.js","sources":["../../resolveBindingExpression.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { BindingExpression, BindingNullBehavior, BindingSourceKind } from '@cratis/scene.model';\nimport { BindingScope } from './BindingScope';\n\n/**\n * Resolves a typed binding against the shared runtime binding scope.\n */\nexport function resolveBindingExpression(binding: BindingExpression, scope: BindingScope): unknown {\n const kind = binding.kind ?? BindingSourceKind.DataContext;\n if (kind === BindingSourceKind.Literal) return binding.value;\n\n const source = sourceValue(binding, scope, kind);\n const value = readPath(source, sourcePath(binding, kind));\n if (value !== null && value !== undefined) return value;\n\n if (binding.nullBehavior === BindingNullBehavior.Preserve) return undefined;\n if (binding.nullBehavior === BindingNullBehavior.Clear) return null;\n return value;\n}\n\n/**\n * Creates a legacy resolver function from a binding scope.\n */\nexport function createBindingResolver(scope: BindingScope): (binding: BindingExpression) => unknown {\n return binding => resolveBindingExpression(binding, scope);\n}\n\nfunction sourceValue(binding: BindingExpression, scope: BindingScope, kind: BindingSourceKind): unknown {\n switch (kind) {\n case BindingSourceKind.DataContext:\n return scope.dataContext;\n case BindingSourceKind.QueryResult:\n return binding.query ? scope.queryResults?.[binding.query] : undefined;\n case BindingSourceKind.ComponentProperty:\n return binding.componentId ? scope.componentOutputs?.[binding.componentId] : undefined;\n case BindingSourceKind.Literal:\n return binding.value;\n }\n}\n\nfunction sourcePath(binding: BindingExpression, kind: BindingSourceKind): string {\n if (kind === BindingSourceKind.ComponentProperty) return binding.componentPropertyPath ?? binding.path;\n return binding.path;\n}\n\nfunction readPath(source: unknown, path: string): unknown {\n if (!path) return source;\n return path.split('.').reduce<unknown>((current, segment) => {\n if (current === null || current === undefined) return undefined;\n if (typeof current !== 'object') return undefined;\n return (current as Record<string, unknown>)[segment];\n }, source);\n}\n"],"names":["resolveBindingExpression","binding","scope","kind","BindingSourceKind","DataContext","Literal","value","source","sourceValue","readPath","sourcePath","undefined","nullBehavior","BindingNullBehavior","Preserve","Clear","createBindingResolver","dataContext","QueryResult","query","queryResults","ComponentProperty","componentId","componentOutputs","componentPropertyPath","path","split","reduce","current","segment"],"mappings":";;AAAA;AACA;AAKA;;AAEC,IACM,SAASA,wBAAAA,CAAyBC,OAA0B,EAAEC,KAAmB,EAAA;AACpF,IAAA,MAAMC,IAAAA,GAAOF,OAAAA,CAAQE,IAAI,IAAIC,kBAAkBC,WAAW;AAC1D,IAAA,IAAIF,SAASC,iBAAAA,CAAkBE,OAAO,EAAE,OAAOL,QAAQM,KAAK;IAE5D,MAAMC,MAAAA,GAASC,WAAAA,CAAYR,OAAAA,EAASC,KAAAA,EAAOC,IAAAA,CAAAA;AAC3C,IAAA,MAAMI,KAAAA,GAAQG,QAAAA,CAASF,MAAAA,EAAQG,UAAAA,CAAWV,OAAAA,EAASE,IAAAA,CAAAA,CAAAA;AACnD,IAAA,IAAII,KAAAA,KAAU,IAAA,IAAQA,KAAAA,KAAUK,SAAAA,EAAW,OAAOL,KAAAA;AAElD,IAAA,IAAIN,QAAQY,YAAY,KAAKC,mBAAAA,CAAoBC,QAAQ,EAAE,OAAOH,SAAAA;AAClE,IAAA,IAAIX,QAAQY,YAAY,KAAKC,mBAAAA,CAAoBE,KAAK,EAAE,OAAO,IAAA;IAC/D,OAAOT,KAAAA;AACX;AAEA;;IAGO,SAASU,qBAAAA,CAAsBf,KAAmB,EAAA;IACrD,OAAOD,CAAAA,OAAAA,GAAWD,wBAAAA,CAAyBC,OAAAA,EAASC,KAAAA,CAAAA;AACxD;AAEA,SAASO,WAAAA,CAAYR,OAA0B,EAAEC,KAAmB,EAAEC,IAAuB,EAAA;IACzF,OAAQA,IAAAA;AACJ,QAAA,KAAKC,kBAAkBC,WAAW;AAC9B,YAAA,OAAOH,MAAMgB,WAAW;AAC5B,QAAA,KAAKd,kBAAkBe,WAAW;YAC9B,OAAOlB,OAAAA,CAAQmB,KAAK,GAAGlB,KAAAA,CAAMmB,YAAY,GAAGpB,OAAAA,CAAQmB,KAAK,CAAC,GAAGR,SAAAA;AACjE,QAAA,KAAKR,kBAAkBkB,iBAAiB;YACpC,OAAOrB,OAAAA,CAAQsB,WAAW,GAAGrB,KAAAA,CAAMsB,gBAAgB,GAAGvB,OAAAA,CAAQsB,WAAW,CAAC,GAAGX,SAAAA;AACjF,QAAA,KAAKR,kBAAkBE,OAAO;AAC1B,YAAA,OAAOL,QAAQM,KAAK;AAC5B;AACJ;AAEA,SAASI,UAAAA,CAAWV,OAA0B,EAAEE,IAAuB,EAAA;IACnE,IAAIA,IAAAA,KAASC,kBAAkBkB,iBAAiB,EAAE,OAAOrB,OAAAA,CAAQwB,qBAAqB,IAAIxB,OAAAA,CAAQyB,IAAI;AACtG,IAAA,OAAOzB,QAAQyB,IAAI;AACvB;AAEA,SAAShB,QAAAA,CAASF,MAAe,EAAEkB,IAAY,EAAA;IAC3C,IAAI,CAACA,MAAM,OAAOlB,MAAAA;AAClB,IAAA,OAAOkB,KAAKC,KAAK,CAAC,KAAKC,MAAM,CAAU,CAACC,OAAAA,EAASC,OAAAA,GAAAA;AAC7C,QAAA,IAAID,OAAAA,KAAY,IAAA,IAAQA,OAAAA,KAAYjB,SAAAA,EAAW,OAAOA,SAAAA;QACtD,IAAI,OAAOiB,OAAAA,KAAY,QAAA,EAAU,OAAOjB,SAAAA;QACxC,OAAQiB,OAAmC,CAACC,OAAAA,CAAQ;IACxD,CAAA,EAAGtB,MAAAA,CAAAA;AACP;;"}
1
+ {"version":3,"file":"resolveBindingExpression.js","sources":["../../resolveBindingExpression.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { BindingExpression, BindingNullBehavior, BindingSourceKind } from '@cratis/scene.model';\nimport { BindingScope } from './BindingScope';\n\n/**\n * Resolves a typed binding against the shared runtime binding scope.\n */\nexport function resolveBindingExpression(binding: BindingExpression, scope: BindingScope): unknown {\n const kind = binding.kind ?? BindingSourceKind.DataContext;\n\n // A literal without a value is absent, whether the author wrote `null` or nothing: the C# model cannot\n // tell the two apart, and both engines must resolve the same document to the same value.\n const value = kind === BindingSourceKind.Literal\n ? binding.value ?? undefined\n : readPath(sourceValue(binding, scope, kind), sourcePath(binding, kind));\n if (value !== null && value !== undefined) return value;\n\n if (binding.nullBehavior === BindingNullBehavior.Preserve) return undefined;\n if (binding.nullBehavior === BindingNullBehavior.Clear) return null;\n return value;\n}\n\n/**\n * Creates a legacy resolver function from a binding scope.\n */\nexport function createBindingResolver(scope: BindingScope): (binding: BindingExpression) => unknown {\n return binding => resolveBindingExpression(binding, scope);\n}\n\nfunction sourceValue(binding: BindingExpression, scope: BindingScope, kind: BindingSourceKind): unknown {\n switch (kind) {\n case BindingSourceKind.DataContext:\n return scope.dataContext ?? undefined;\n case BindingSourceKind.QueryResult:\n return binding.query ? scope.queryResults?.[binding.query] : undefined;\n case BindingSourceKind.ComponentProperty:\n return binding.componentId ? scope.componentOutputs?.[binding.componentId] : undefined;\n case BindingSourceKind.Literal:\n return binding.value;\n }\n}\n\nfunction sourcePath(binding: BindingExpression, kind: BindingSourceKind): string {\n if (kind === BindingSourceKind.ComponentProperty) return binding.componentPropertyPath ?? binding.path;\n return binding.path;\n}\n\n/**\n * Reads a dotted path. Only own properties and array indexes are read - never inherited members such as\n * `constructor` - and anything that is not an object or array ends the walk, so the C# engine can follow\n * exactly the same rule over JSON.\n */\nfunction readPath(source: unknown, path: string): unknown {\n if (!path) return source;\n return path.split('.').reduce<unknown>((current, segment) => {\n if (current === null || current === undefined || typeof current !== 'object') return undefined;\n if (Array.isArray(current)) return /^(0|[1-9][0-9]*)$/.test(segment) ? current[Number(segment)] : undefined;\n return Object.hasOwn(current, segment) ? (current as Record<string, unknown>)[segment] : undefined;\n }, source);\n}\n"],"names":["resolveBindingExpression","binding","scope","kind","BindingSourceKind","DataContext","value","Literal","undefined","readPath","sourceValue","sourcePath","nullBehavior","BindingNullBehavior","Preserve","Clear","createBindingResolver","dataContext","QueryResult","query","queryResults","ComponentProperty","componentId","componentOutputs","componentPropertyPath","path","source","split","reduce","current","segment","Array","isArray","test","Number","Object","hasOwn"],"mappings":";;AAAA;AACA;AAKA;;AAEC,IACM,SAASA,wBAAAA,CAAyBC,OAA0B,EAAEC,KAAmB,EAAA;AACpF,IAAA,MAAMC,IAAAA,GAAOF,OAAAA,CAAQE,IAAI,IAAIC,kBAAkBC,WAAW;;;AAI1D,IAAA,MAAMC,KAAAA,GAAQH,IAAAA,KAASC,iBAAAA,CAAkBG,OAAO,GAC1CN,OAAAA,CAAQK,KAAK,IAAIE,SAAAA,GACjBC,SAASC,WAAAA,CAAYT,OAAAA,EAASC,KAAAA,EAAOC,IAAAA,CAAAA,EAAOQ,WAAWV,OAAAA,EAASE,IAAAA,CAAAA,CAAAA;AACtE,IAAA,IAAIG,KAAAA,KAAU,IAAA,IAAQA,KAAAA,KAAUE,SAAAA,EAAW,OAAOF,KAAAA;AAElD,IAAA,IAAIL,QAAQW,YAAY,KAAKC,mBAAAA,CAAoBC,QAAQ,EAAE,OAAON,SAAAA;AAClE,IAAA,IAAIP,QAAQW,YAAY,KAAKC,mBAAAA,CAAoBE,KAAK,EAAE,OAAO,IAAA;IAC/D,OAAOT,KAAAA;AACX;AAEA;;IAGO,SAASU,qBAAAA,CAAsBd,KAAmB,EAAA;IACrD,OAAOD,CAAAA,OAAAA,GAAWD,wBAAAA,CAAyBC,OAAAA,EAASC,KAAAA,CAAAA;AACxD;AAEA,SAASQ,WAAAA,CAAYT,OAA0B,EAAEC,KAAmB,EAAEC,IAAuB,EAAA;IACzF,OAAQA,IAAAA;AACJ,QAAA,KAAKC,kBAAkBC,WAAW;YAC9B,OAAOH,KAAAA,CAAMe,WAAW,IAAIT,SAAAA;AAChC,QAAA,KAAKJ,kBAAkBc,WAAW;YAC9B,OAAOjB,OAAAA,CAAQkB,KAAK,GAAGjB,KAAAA,CAAMkB,YAAY,GAAGnB,OAAAA,CAAQkB,KAAK,CAAC,GAAGX,SAAAA;AACjE,QAAA,KAAKJ,kBAAkBiB,iBAAiB;YACpC,OAAOpB,OAAAA,CAAQqB,WAAW,GAAGpB,KAAAA,CAAMqB,gBAAgB,GAAGtB,OAAAA,CAAQqB,WAAW,CAAC,GAAGd,SAAAA;AACjF,QAAA,KAAKJ,kBAAkBG,OAAO;AAC1B,YAAA,OAAON,QAAQK,KAAK;AAC5B;AACJ;AAEA,SAASK,UAAAA,CAAWV,OAA0B,EAAEE,IAAuB,EAAA;IACnE,IAAIA,IAAAA,KAASC,kBAAkBiB,iBAAiB,EAAE,OAAOpB,OAAAA,CAAQuB,qBAAqB,IAAIvB,OAAAA,CAAQwB,IAAI;AACtG,IAAA,OAAOxB,QAAQwB,IAAI;AACvB;AAEA;;;;AAIC,IACD,SAAShB,QAAAA,CAASiB,MAAe,EAAED,IAAY,EAAA;IAC3C,IAAI,CAACA,MAAM,OAAOC,MAAAA;AAClB,IAAA,OAAOD,KAAKE,KAAK,CAAC,KAAKC,MAAM,CAAU,CAACC,OAAAA,EAASC,OAAAA,GAAAA;AAC7C,QAAA,IAAID,YAAY,IAAA,IAAQA,OAAAA,KAAYrB,aAAa,OAAOqB,OAAAA,KAAY,UAAU,OAAOrB,SAAAA;AACrF,QAAA,IAAIuB,KAAAA,CAAMC,OAAO,CAACH,OAAAA,CAAAA,EAAU,OAAO,mBAAA,CAAoBI,IAAI,CAACH,OAAAA,CAAAA,GAAWD,OAAO,CAACK,MAAAA,CAAOJ,SAAS,GAAGtB,SAAAA;QAClG,OAAO2B,MAAAA,CAAOC,MAAM,CAACP,OAAAA,EAASC,WAAW,OAAoC,CAACA,OAAAA,CAAQ,GAAGtB,SAAAA;IAC7F,CAAA,EAAGkB,MAAAA,CAAAA;AACP;;"}