@cratis/scene.blueprint.default 4.33.0 → 4.34.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 (134) hide show
  1. package/dist/cjs/index.js +53 -4
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/preview-host/ApplicationDocument.js +17 -0
  4. package/dist/cjs/preview-host/ApplicationDocument.js.map +1 -0
  5. package/dist/cjs/preview-host/ApplicationHost.js +113 -0
  6. package/dist/cjs/preview-host/ApplicationHost.js.map +1 -0
  7. package/dist/cjs/preview-host/FlowArrangementView.js +75 -0
  8. package/dist/cjs/preview-host/FlowArrangementView.js.map +1 -0
  9. package/dist/cjs/preview-host/PreviewProblem.js +32 -0
  10. package/dist/cjs/preview-host/PreviewProblem.js.map +1 -0
  11. package/dist/cjs/preview-host/PreviewProblemsView.js +51 -0
  12. package/dist/cjs/preview-host/PreviewProblemsView.js.map +1 -0
  13. package/dist/cjs/preview-host/PreviewSliceFragment.js +55 -0
  14. package/dist/cjs/preview-host/PreviewSliceFragment.js.map +1 -0
  15. package/dist/cjs/preview-host/PreviewTarget.js +17 -0
  16. package/dist/cjs/preview-host/PreviewTarget.js.map +1 -0
  17. package/dist/cjs/preview-host/PreviewTemplate.js +49 -0
  18. package/dist/cjs/preview-host/PreviewTemplate.js.map +1 -0
  19. package/dist/cjs/preview-host/PreviewToast.js +45 -0
  20. package/dist/cjs/preview-host/PreviewToast.js.map +1 -0
  21. package/dist/cjs/preview-host/ScenePreviewHost.js +290 -0
  22. package/dist/cjs/preview-host/ScenePreviewHost.js.map +1 -0
  23. package/dist/cjs/preview-host/composeApplication.js +249 -0
  24. package/dist/cjs/preview-host/composeApplication.js.map +1 -0
  25. package/dist/cjs/preview-host/defaultApplicationChrome.js +43 -0
  26. package/dist/cjs/preview-host/defaultApplicationChrome.js.map +1 -0
  27. package/dist/cjs/preview-host/diagnosePreview.js +100 -0
  28. package/dist/cjs/preview-host/diagnosePreview.js.map +1 -0
  29. package/dist/cjs/preview-host/previewProfile.js +53 -0
  30. package/dist/cjs/preview-host/previewProfile.js.map +1 -0
  31. package/dist/cjs/preview-host/previewSampleData.js +116 -0
  32. package/dist/cjs/preview-host/previewSampleData.js.map +1 -0
  33. package/dist/cjs/preview-host/resolvePreviewPlan.js +126 -0
  34. package/dist/cjs/preview-host/resolvePreviewPlan.js.map +1 -0
  35. package/dist/cjs/preview-host/useSizeClass.js +23 -0
  36. package/dist/cjs/preview-host/useSizeClass.js.map +1 -0
  37. package/dist/esm/index.d.ts +1 -0
  38. package/dist/esm/index.d.ts.map +1 -1
  39. package/dist/esm/index.js +17 -0
  40. package/dist/esm/index.js.map +1 -1
  41. package/dist/esm/preview-host/ApplicationDocument.d.ts +7 -0
  42. package/dist/esm/preview-host/ApplicationDocument.d.ts.map +1 -0
  43. package/dist/esm/preview-host/ApplicationDocument.js +15 -0
  44. package/dist/esm/preview-host/ApplicationDocument.js.map +1 -0
  45. package/dist/esm/preview-host/ApplicationHost.d.ts +21 -0
  46. package/dist/esm/preview-host/ApplicationHost.d.ts.map +1 -0
  47. package/dist/esm/preview-host/ApplicationHost.js +111 -0
  48. package/dist/esm/preview-host/ApplicationHost.js.map +1 -0
  49. package/dist/esm/preview-host/FlowArrangementView.d.ts +7 -0
  50. package/dist/esm/preview-host/FlowArrangementView.d.ts.map +1 -0
  51. package/dist/esm/preview-host/FlowArrangementView.js +73 -0
  52. package/dist/esm/preview-host/FlowArrangementView.js.map +1 -0
  53. package/dist/esm/preview-host/PreviewProblem.d.ts +26 -0
  54. package/dist/esm/preview-host/PreviewProblem.d.ts.map +1 -0
  55. package/dist/esm/preview-host/PreviewProblem.js +28 -0
  56. package/dist/esm/preview-host/PreviewProblem.js.map +1 -0
  57. package/dist/esm/preview-host/PreviewProblemsView.d.ts +7 -0
  58. package/dist/esm/preview-host/PreviewProblemsView.d.ts.map +1 -0
  59. package/dist/esm/preview-host/PreviewProblemsView.js +49 -0
  60. package/dist/esm/preview-host/PreviewProblemsView.js.map +1 -0
  61. package/dist/esm/preview-host/PreviewSliceFragment.d.ts +3 -0
  62. package/dist/esm/preview-host/PreviewSliceFragment.d.ts.map +1 -0
  63. package/dist/esm/preview-host/PreviewSliceFragment.js +53 -0
  64. package/dist/esm/preview-host/PreviewSliceFragment.js.map +1 -0
  65. package/dist/esm/preview-host/PreviewTarget.d.ts +10 -0
  66. package/dist/esm/preview-host/PreviewTarget.d.ts.map +1 -0
  67. package/dist/esm/preview-host/PreviewTarget.js +15 -0
  68. package/dist/esm/preview-host/PreviewTarget.js.map +1 -0
  69. package/dist/esm/preview-host/PreviewTemplate.d.ts +5 -0
  70. package/dist/esm/preview-host/PreviewTemplate.d.ts.map +1 -0
  71. package/dist/esm/preview-host/PreviewTemplate.js +45 -0
  72. package/dist/esm/preview-host/PreviewTemplate.js.map +1 -0
  73. package/dist/esm/preview-host/PreviewToast.d.ts +10 -0
  74. package/dist/esm/preview-host/PreviewToast.d.ts.map +1 -0
  75. package/dist/esm/preview-host/PreviewToast.js +43 -0
  76. package/dist/esm/preview-host/PreviewToast.js.map +1 -0
  77. package/dist/esm/preview-host/ScenePreviewHost.d.ts +32 -0
  78. package/dist/esm/preview-host/ScenePreviewHost.d.ts.map +1 -0
  79. package/dist/esm/preview-host/ScenePreviewHost.js +288 -0
  80. package/dist/esm/preview-host/ScenePreviewHost.js.map +1 -0
  81. package/dist/esm/preview-host/composeApplication.d.ts +34 -0
  82. package/dist/esm/preview-host/composeApplication.d.ts.map +1 -0
  83. package/dist/esm/preview-host/composeApplication.js +239 -0
  84. package/dist/esm/preview-host/composeApplication.js.map +1 -0
  85. package/dist/esm/preview-host/defaultApplicationChrome.d.ts +4 -0
  86. package/dist/esm/preview-host/defaultApplicationChrome.d.ts.map +1 -0
  87. package/dist/esm/preview-host/defaultApplicationChrome.js +41 -0
  88. package/dist/esm/preview-host/defaultApplicationChrome.js.map +1 -0
  89. package/dist/esm/preview-host/diagnosePreview.d.ts +22 -0
  90. package/dist/esm/preview-host/diagnosePreview.d.ts.map +1 -0
  91. package/dist/esm/preview-host/diagnosePreview.js +98 -0
  92. package/dist/esm/preview-host/diagnosePreview.js.map +1 -0
  93. package/dist/esm/preview-host/index.d.ts +18 -0
  94. package/dist/esm/preview-host/index.d.ts.map +1 -0
  95. package/dist/esm/preview-host/index.js +18 -0
  96. package/dist/esm/preview-host/index.js.map +1 -0
  97. package/dist/esm/preview-host/previewProfile.d.ts +6 -0
  98. package/dist/esm/preview-host/previewProfile.d.ts.map +1 -0
  99. package/dist/esm/preview-host/previewProfile.js +49 -0
  100. package/dist/esm/preview-host/previewProfile.js.map +1 -0
  101. package/dist/esm/preview-host/previewSampleData.d.ts +22 -0
  102. package/dist/esm/preview-host/previewSampleData.d.ts.map +1 -0
  103. package/dist/esm/preview-host/previewSampleData.js +113 -0
  104. package/dist/esm/preview-host/previewSampleData.js.map +1 -0
  105. package/dist/esm/preview-host/resolvePreviewPlan.d.ts +18 -0
  106. package/dist/esm/preview-host/resolvePreviewPlan.d.ts.map +1 -0
  107. package/dist/esm/preview-host/resolvePreviewPlan.js +124 -0
  108. package/dist/esm/preview-host/resolvePreviewPlan.js.map +1 -0
  109. package/dist/esm/preview-host/useSizeClass.d.ts +3 -0
  110. package/dist/esm/preview-host/useSizeClass.d.ts.map +1 -0
  111. package/dist/esm/preview-host/useSizeClass.js +21 -0
  112. package/dist/esm/preview-host/useSizeClass.js.map +1 -0
  113. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  114. package/index.ts +1 -0
  115. package/package.json +8 -8
  116. package/preview-host/ApplicationDocument.ts +31 -0
  117. package/preview-host/ApplicationHost.tsx +114 -0
  118. package/preview-host/FlowArrangementView.tsx +59 -0
  119. package/preview-host/PreviewProblem.ts +68 -0
  120. package/preview-host/PreviewProblemsView.tsx +31 -0
  121. package/preview-host/PreviewSliceFragment.ts +43 -0
  122. package/preview-host/PreviewTarget.ts +19 -0
  123. package/preview-host/PreviewTemplate.tsx +45 -0
  124. package/preview-host/PreviewToast.tsx +32 -0
  125. package/preview-host/ScenePreviewHost.tsx +250 -0
  126. package/preview-host/composeApplication.ts +273 -0
  127. package/preview-host/defaultApplicationChrome.ts +33 -0
  128. package/preview-host/diagnosePreview.ts +132 -0
  129. package/preview-host/index.ts +20 -0
  130. package/preview-host/previewProfile.ts +47 -0
  131. package/preview-host/previewSampleData.ts +144 -0
  132. package/preview-host/resolvePreviewPlan.ts +100 -0
  133. package/preview-host/useSizeClass.ts +23 -0
  134. package/shell/layout.css +22 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"previewProfile.js","sources":["../../../preview-host/previewProfile.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 type { UiProfile } from '@cratis/scene.model';\nimport type { PackageCatalog } from '@cratis/scene.engine';\nimport { ComponentName } from '../ComponentName';\nimport { defaultBlueprintName } from '../packageName';\nimport { coreComponents } from '@cratis/scene.react';\n\n/** The packages every preview and Stage application resolves bare component names against, in ascending priority. */\nexport const requiredPackages = ['core', defaultBlueprintName];\n\n/** What the packages every host has declare, so a bare name resolves to the package that provides it. */\nexport const blueprintPackageCatalog: PackageCatalog = {\n core: Object.keys(coreComponents).map(key => key.slice(key.indexOf(':') + 1)),\n [defaultBlueprintName]: Object.values(ComponentName),\n};\n\n/**\n * The profile an application renders against: the document's own web profile (else its first), with the packages every host\n * renders with admitted even when the model never named them - without that, a template written against the blueprint's\n * vocabulary would come out as a column of dashed placeholders. A host with more packages (PrimeReact, a custom set) lists them\n * in `additionalPackages`.\n *\n * The profile's `sampleData` is carried through: it is where the application chose its active pack (spec 11, SD3).\n *\n * @param profiles The profiles the document declares.\n * @param additionalPackages Packages the host renders with beyond the required ones, lowest priority first.\n * @returns The profile to resolve component names with.\n */\nexport function previewProfile(profiles: UiProfile[] | undefined, additionalPackages: string[] = []): UiProfile {\n const declared = profiles?.find(profile => profile.targetPlatform === 'web') ?? profiles?.[0];\n const packages = [...(declared?.packages ?? [])];\n for (const required of [...requiredPackages, ...additionalPackages]) {\n if (!packages.includes(required)) packages.push(required);\n }\n\n return {\n name: declared?.name ?? 'Preview',\n targetPlatform: declared?.targetPlatform ?? 'web',\n packages,\n defaultSizeClass: declared?.defaultSizeClass,\n layout: declared?.layout,\n theme: declared?.theme,\n sampleData: declared?.sampleData,\n };\n}\n"],"names":["requiredPackages","defaultBlueprintName","blueprintPackageCatalog","core","Object","keys","coreComponents","map","key","slice","indexOf","values","ComponentName","previewProfile","profiles","additionalPackages","declared","find","profile","targetPlatform","packages","required","includes","push","name","defaultSizeClass","layout","theme","sampleData"],"mappings":";;;;AAAA;AACA;AAQA,sHACO,MAAMA,gBAAAA,GAAmB;AAAC,IAAA,MAAA;AAAQC,IAAAA;;AAEzC,0GACO,MAAMC,uBAAAA,GAA0C;AACnDC,IAAAA,IAAAA,EAAMC,MAAAA,CAAOC,IAAI,CAACC,cAAAA,CAAAA,CAAgBC,GAAG,CAACC,CAAAA,GAAAA,GAAOA,GAAAA,CAAIC,KAAK,CAACD,GAAAA,CAAIE,OAAO,CAAC,GAAA,CAAA,GAAO,CAAA,CAAA,CAAA;AAC1E,IAAA,CAACT,oBAAAA,GAAuBG,MAAAA,CAAOO,MAAM,CAACC,aAAAA;AAC1C;AAEA;;;;;;;;;;;AAWC,IACM,SAASC,cAAAA,CAAeC,QAAiC,EAAEC,qBAA+B,EAAE,EAAA;IAC/F,MAAMC,QAAAA,GAAWF,QAAAA,EAAUG,IAAAA,CAAKC,CAAAA,OAAAA,GAAWA,OAAAA,CAAQC,cAAc,KAAK,KAAA,CAAA,IAAUL,QAAAA,GAAW,CAAA,CAAE;AAC7F,IAAA,MAAMM,QAAAA,GAAW;AAAKJ,QAAAA,GAAAA,QAAAA,EAAUI,YAAY;AAAI,KAAA;AAChD,IAAA,KAAK,MAAMC,QAAAA,IAAY;AAAIrB,QAAAA,GAAAA,gBAAAA;AAAqBe,QAAAA,GAAAA;KAAmB,CAAE;AACjE,QAAA,IAAI,CAACK,QAAAA,CAASE,QAAQ,CAACD,QAAAA,CAAAA,EAAWD,QAAAA,CAASG,IAAI,CAACF,QAAAA,CAAAA;AACpD,IAAA;IAEA,OAAO;AACHG,QAAAA,IAAAA,EAAMR,UAAUQ,IAAAA,IAAQ,SAAA;AACxBL,QAAAA,cAAAA,EAAgBH,UAAUG,cAAAA,IAAkB,KAAA;AAC5CC,QAAAA,QAAAA;AACAK,QAAAA,gBAAAA,EAAkBT,QAAAA,EAAUS,gBAAAA;AAC5BC,QAAAA,MAAAA,EAAQV,QAAAA,EAAUU,MAAAA;AAClBC,QAAAA,KAAAA,EAAOX,QAAAA,EAAUW,KAAAA;AACjBC,QAAAA,UAAAA,EAAYZ,QAAAA,EAAUY;AAC1B,KAAA;AACJ;;"}
@@ -0,0 +1,22 @@
1
+ import { SampleDataPack, SampleShape } from '@cratis/scene.model';
2
+ import { BindingResolver, SampleDataResolution } from '@cratis/scene.engine';
3
+ import type { SliceCommandField } from '@cratis/scene.react';
4
+ import { ApplicationDocument } from './ApplicationDocument';
5
+ export interface PreviewSampleData {
6
+ packs: SampleDataPack[];
7
+ sessionActivePack?: string;
8
+ blueprintDefaultPack?: string;
9
+ locale?: string;
10
+ seed?: number;
11
+ rowCount?: number;
12
+ shapes?: Record<string, SampleShape>;
13
+ }
14
+ export interface PreviewSampleDataSource {
15
+ rows(target: string, shape?: SampleShape): SampleDataResolution;
16
+ queryResults: Record<string, unknown>;
17
+ resolveBinding: BindingResolver;
18
+ commandFields(command: string, fields: SliceCommandField[]): SliceCommandField[];
19
+ }
20
+ export declare function collectQueryNames(value: unknown): string[];
21
+ export declare function createPreviewSampleData(application: ApplicationDocument, sample?: PreviewSampleData): PreviewSampleDataSource;
22
+ //# sourceMappingURL=previewSampleData.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"previewSampleData.d.ts","sourceRoot":"","sources":["../../../preview-host/previewSampleData.ts"],"names":[],"mappings":"AAGA,OAAO,EAAqB,cAAc,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAqB,MAAM,sBAAsB,CAAC;AAChG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAS5D,MAAM,WAAW,iBAAiB;IAE9B,KAAK,EAAE,cAAc,EAAE,CAAC;IAGxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAG3B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAG9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAGhB,IAAI,CAAC,EAAE,MAAM,CAAC;IAGd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAGlB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACxC;AAGD,MAAM,WAAW,uBAAuB;IAEpC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,oBAAoB,CAAC;IAGhE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAGtC,cAAc,EAAE,eAAe,CAAC;IAGhC,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,GAAG,iBAAiB,EAAE,CAAC;CACpF;AAKD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAiB1D;AA2BD,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,mBAAmB,EAAE,MAAM,GAAE,iBAA4B,GAAG,uBAAuB,CA2CvI"}
@@ -0,0 +1,113 @@
1
+ import { resolveSampleData } from '@cratis/scene.engine';
2
+ import { previewProfile } from './previewProfile.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
+ const noSample = {
7
+ packs: []
8
+ };
9
+ /** The names of the queries a document binds: every `query` it names, in bindings and on components. */ function collectQueryNames(value) {
10
+ const names = new Set();
11
+ const visit = (candidate)=>{
12
+ if (candidate === null || typeof candidate !== 'object') return;
13
+ if (Array.isArray(candidate)) {
14
+ candidate.forEach(visit);
15
+ return;
16
+ }
17
+ for (const [key, entry] of Object.entries(candidate)){
18
+ if (key === 'query' && typeof entry === 'string' && entry.length > 0) names.add(entry);
19
+ else visit(entry);
20
+ }
21
+ };
22
+ visit(value);
23
+ return [
24
+ ...names
25
+ ];
26
+ }
27
+ function readPath(source, path) {
28
+ if (!path) return source;
29
+ return path.split('.').reduce((current, segment)=>{
30
+ if (current === null || current === undefined || typeof current !== 'object') return undefined;
31
+ if (Array.isArray(current)) return /^(0|[1-9][0-9]*)$/.test(segment) ? current[Number(segment)] : undefined;
32
+ return Object.hasOwn(current, segment) ? current[segment] : undefined;
33
+ }, source);
34
+ }
35
+ function shapeOfFields(name, fields) {
36
+ return {
37
+ name,
38
+ fields: fields.map((field)=>({
39
+ name: field.name,
40
+ type: field.type
41
+ }))
42
+ };
43
+ }
44
+ function scalar(value) {
45
+ return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' ? value : undefined;
46
+ }
47
+ /**
48
+ * Plugs the sample data resolution into what a preview renders with (PRV6). Nothing here decides what a row looks like - that is
49
+ * `resolveSampleData` - this only asks it, with the application profile's selection, for the queries the document binds and the
50
+ * commands its slices accept. It is design/preview time only: a production host never builds one (SD6).
51
+ *
52
+ * @param application The document whose profile carries the selection and whose bindings are scanned.
53
+ * @param sample The packs, session override and seed.
54
+ */ function createPreviewSampleData(application, sample = noSample) {
55
+ const profile = previewProfile(application.uiProfiles);
56
+ const context = {
57
+ packs: sample.packs,
58
+ profile,
59
+ sessionActivePack: sample.sessionActivePack,
60
+ blueprintDefaultPack: sample.blueprintDefaultPack,
61
+ locale: sample.locale,
62
+ seed: sample.seed,
63
+ rowCount: sample.rowCount,
64
+ isDesignOrPreview: true
65
+ };
66
+ const rows = (target, shape)=>{
67
+ const known = shape ?? sample.shapes?.[target];
68
+ const resolved = resolveSampleData({
69
+ target,
70
+ ...known === undefined ? {} : {
71
+ shape: known
72
+ }
73
+ }, context);
74
+ if (resolved.rows.length > 0 || !target.includes('.')) return resolved;
75
+ const short = target.slice(target.lastIndexOf('.') + 1);
76
+ return resolveSampleData({
77
+ target: short,
78
+ ...known === undefined ? {} : {
79
+ shape: known
80
+ }
81
+ }, context);
82
+ };
83
+ const queryResults = {};
84
+ for (const name of collectQueryNames([
85
+ application.screens,
86
+ application.screenTemplates,
87
+ application.dialogTemplates ?? [],
88
+ application.layouts
89
+ ])){
90
+ const resolved = rows(name);
91
+ if (resolved.rows.length > 0) queryResults[name] = resolved.rows;
92
+ }
93
+ return {
94
+ rows,
95
+ queryResults,
96
+ resolveBinding: (binding)=>binding.query ? readPath(queryResults[binding.query], binding.path) : undefined,
97
+ commandFields: (command, fields)=>{
98
+ const first = rows(command, shapeOfFields(command, fields)).rows[0];
99
+ if (!first) return fields;
100
+ return fields.map((field)=>{
101
+ const key = Object.keys(first).find((candidate)=>candidate.toLowerCase() === field.name.toLowerCase());
102
+ const value = key === undefined ? undefined : scalar(first[key]);
103
+ return value === undefined ? field : {
104
+ ...field,
105
+ initialValue: value
106
+ };
107
+ });
108
+ }
109
+ };
110
+ }
111
+
112
+ export { collectQueryNames, createPreviewSampleData };
113
+ //# sourceMappingURL=previewSampleData.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"previewSampleData.js","sources":["../../../preview-host/previewSampleData.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, SampleDataPack, SampleShape } from '@cratis/scene.model';\nimport { BindingResolver, SampleDataResolution, resolveSampleData } from '@cratis/scene.engine';\nimport type { SliceCommandField } from '@cratis/scene.react';\nimport { ApplicationDocument } from './ApplicationDocument';\nimport { previewProfile } from './previewProfile';\n\n/**\n * Which sample data a preview shows (spec 11, PRV6). The active pack is the application profile's (`sampleData.activePack`),\n * chosen once for the whole application; `sessionActivePack` is the preview strip's selector, a session-only override of that\n * setting - not a second source of truth. Resolution is `resolveSampleData`'s: bound pack, active pack, the blueprint's default\n * pack, then generated data, and the same seed gives the same rows every time.\n */\nexport interface PreviewSampleData {\n /** Every pack available: the blueprints' and the author's own. */\n packs: SampleDataPack[];\n\n /** The preview strip's choice for this session: a pack id, or the empty string for generated data. Absent leaves the profile's. */\n sessionActivePack?: string;\n\n /** The default pack of the blueprint the templates came from. */\n blueprintDefaultPack?: string;\n\n /** The locale of generated data when no pack supplies one. */\n locale?: string;\n\n /** The seed for generated data; 1 by default, so previews are stable. */\n seed?: number;\n\n /** The number of generated rows. */\n rowCount?: number;\n\n /** The shape of the rows of each read model or query, by name, for generating rows where no pack has them. */\n shapes?: Record<string, SampleShape>;\n}\n\n/** What a preview reads its data from. */\nexport interface PreviewSampleDataSource {\n /** The rows for a read model or query; empty when nothing supplies any. */\n rows(target: string, shape?: SampleShape): SampleDataResolution;\n\n /** The rows of every query the document binds, by query name - the `queryResults` of the render scope. */\n queryResults: Record<string, unknown>;\n\n /** Resolves a binding that names a query against the sample rows. */\n resolveBinding: BindingResolver;\n\n /** Starting values for a command's fields from the sample rows, for the task dialog of a slice. */\n commandFields(command: string, fields: SliceCommandField[]): SliceCommandField[];\n}\n\nconst noSample: PreviewSampleData = { packs: [] };\n\n/** The names of the queries a document binds: every `query` it names, in bindings and on components. */\nexport function collectQueryNames(value: unknown): string[] {\n const names = new Set<string>();\n const visit = (candidate: unknown) => {\n if (candidate === null || typeof candidate !== 'object') return;\n if (Array.isArray(candidate)) {\n candidate.forEach(visit);\n return;\n }\n\n for (const [key, entry] of Object.entries(candidate as Record<string, unknown>)) {\n if (key === 'query' && typeof entry === 'string' && entry.length > 0) names.add(entry);\n else visit(entry);\n }\n };\n\n visit(value);\n return [...names];\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 || 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\nfunction shapeOfFields(name: string, fields: SliceCommandField[]): SampleShape {\n return { name, fields: fields.map(field => ({ name: field.name, type: field.type })) };\n}\n\nfunction scalar(value: unknown): string | number | boolean | undefined {\n return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' ? value : undefined;\n}\n\n/**\n * Plugs the sample data resolution into what a preview renders with (PRV6). Nothing here decides what a row looks like - that is\n * `resolveSampleData` - this only asks it, with the application profile's selection, for the queries the document binds and the\n * commands its slices accept. It is design/preview time only: a production host never builds one (SD6).\n *\n * @param application The document whose profile carries the selection and whose bindings are scanned.\n * @param sample The packs, session override and seed.\n */\nexport function createPreviewSampleData(application: ApplicationDocument, sample: PreviewSampleData = noSample): PreviewSampleDataSource {\n const profile = previewProfile(application.uiProfiles);\n const context = {\n packs: sample.packs,\n profile,\n sessionActivePack: sample.sessionActivePack,\n blueprintDefaultPack: sample.blueprintDefaultPack,\n locale: sample.locale,\n seed: sample.seed,\n rowCount: sample.rowCount,\n isDesignOrPreview: true,\n };\n\n const rows = (target: string, shape?: SampleShape): SampleDataResolution => {\n const known = shape ?? sample.shapes?.[target];\n const resolved = resolveSampleData({ target, ...(known === undefined ? {} : { shape: known }) }, context);\n if (resolved.rows.length > 0 || !target.includes('.')) return resolved;\n\n const short = target.slice(target.lastIndexOf('.') + 1);\n return resolveSampleData({ target: short, ...(known === undefined ? {} : { shape: known }) }, context);\n };\n\n const queryResults: Record<string, unknown> = {};\n for (const name of collectQueryNames([application.screens, application.screenTemplates, application.dialogTemplates ?? [], application.layouts])) {\n const resolved = rows(name);\n if (resolved.rows.length > 0) queryResults[name] = resolved.rows;\n }\n\n return {\n rows,\n queryResults,\n resolveBinding: (binding: BindingExpression) => binding.query ? readPath(queryResults[binding.query], binding.path) : undefined,\n commandFields: (command, fields) => {\n const first = rows(command, shapeOfFields(command, fields)).rows[0];\n if (!first) return fields;\n\n return fields.map(field => {\n const key = Object.keys(first).find(candidate => candidate.toLowerCase() === field.name.toLowerCase());\n const value = key === undefined ? undefined : scalar(first[key]);\n return value === undefined ? field : { ...field, initialValue: value };\n });\n },\n };\n}\n"],"names":["noSample","packs","collectQueryNames","value","names","Set","visit","candidate","Array","isArray","forEach","key","entry","Object","entries","length","add","readPath","source","path","split","reduce","current","segment","undefined","test","Number","hasOwn","shapeOfFields","name","fields","map","field","type","scalar","createPreviewSampleData","application","sample","profile","previewProfile","uiProfiles","context","sessionActivePack","blueprintDefaultPack","locale","seed","rowCount","isDesignOrPreview","rows","target","shape","known","shapes","resolved","resolveSampleData","includes","short","slice","lastIndexOf","queryResults","screens","screenTemplates","dialogTemplates","layouts","resolveBinding","binding","query","commandFields","command","first","keys","find","toLowerCase","initialValue"],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { ApplicationStructure } from '@cratis/scene.model';
2
+ import { ApplicationStructureIndex } from '@cratis/scene.engine';
3
+ import { PreviewTarget } from './PreviewTarget';
4
+ import { PreviewProblem } from './PreviewProblem';
5
+ export interface PreviewPlan {
6
+ kind: 'module' | 'feature' | 'stateChange' | 'stateView';
7
+ module: string;
8
+ feature?: string;
9
+ slice?: string;
10
+ command?: string;
11
+ breadcrumb: string[];
12
+ }
13
+ export interface PreviewPlanResult {
14
+ plan?: PreviewPlan;
15
+ problems: PreviewProblem[];
16
+ }
17
+ export declare function resolvePreviewPlan(structure: ApplicationStructure | ApplicationStructureIndex, target: PreviewTarget): PreviewPlanResult;
18
+ //# sourceMappingURL=resolvePreviewPlan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolvePreviewPlan.d.ts","sourceRoot":"","sources":["../../../preview-host/resolvePreviewPlan.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,oBAAoB,EAA0B,MAAM,qBAAqB,CAAC;AACnF,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,aAAa,EAAiB,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,cAAc,EAA8C,MAAM,kBAAkB,CAAC;AAG9F,MAAM,WAAW,WAAW;IAExB,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,CAAC;IAGzD,MAAM,EAAE,MAAM,CAAC;IAGf,OAAO,CAAC,EAAE,MAAM,CAAC;IAGjB,KAAK,CAAC,EAAE,MAAM,CAAC;IAGf,OAAO,CAAC,EAAE,MAAM,CAAC;IAGjB,UAAU,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAC9B,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC9B;AAyBD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,oBAAoB,GAAG,yBAAyB,EAAE,MAAM,EAAE,aAAa,GAAG,iBAAiB,CA0CxI"}
@@ -0,0 +1,124 @@
1
+ import { SliceKind } from '@cratis/scene.model';
2
+ import { ApplicationStructureIndex } from '@cratis/scene.engine';
3
+ import { isSliceTarget } from './PreviewTarget.js';
4
+ import { PreviewProblemCode, PreviewProblemSeverity } from './PreviewProblem.js';
5
+
6
+ // Copyright (c) Cratis. All rights reserved.
7
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
8
+ const error = (code, message, nodeId)=>({
9
+ code,
10
+ severity: PreviewProblemSeverity.Error,
11
+ message,
12
+ ...nodeId === undefined ? {} : {
13
+ nodeId
14
+ }
15
+ });
16
+ /** The feature a qualified id names, and the display names of the features above it, outermost first. */ function featurePath(structure, qualified) {
17
+ const [moduleId, ...rest] = qualified.split('.');
18
+ let features = structure.modules.find((module)=>module.id === moduleId)?.features;
19
+ const names = [];
20
+ let found;
21
+ for (const id of rest){
22
+ found = features?.find((candidate)=>candidate.id === id);
23
+ if (!found) return undefined;
24
+ names.push(found.name);
25
+ features = found.features;
26
+ }
27
+ return found ? {
28
+ feature: found,
29
+ names
30
+ } : undefined;
31
+ }
32
+ /**
33
+ * Resolves a preview target against the application structure (PRV3): a module previews its first feature, a feature itself,
34
+ * a slice the page of the feature it belongs to with the slice itself opened (State Change) or isolated (State View).
35
+ * A target that is not in the structure resolves to a problem, not to a blank screen.
36
+ */ function resolvePreviewPlan(structure, target) {
37
+ const index = structure instanceof ApplicationStructureIndex ? structure : new ApplicationStructureIndex(structure);
38
+ if (isSliceTarget(target)) {
39
+ const slice = index.findSlice(target.slice);
40
+ if (!slice) return {
41
+ problems: [
42
+ error(PreviewProblemCode.TargetNotFound, `The slice '${target.slice}' is not in the application.`, target.slice)
43
+ ]
44
+ };
45
+ if (slice.kind === SliceKind.Automation) {
46
+ return {
47
+ problems: [
48
+ error(PreviewProblemCode.SliceNotPreviewable, `The slice '${target.slice}' is an automation: it reacts to events and has nothing to show.`, target.slice)
49
+ ]
50
+ };
51
+ }
52
+ const segments = target.slice.split('.');
53
+ const module = segments[0];
54
+ const featureId = segments.length > 2 ? segments.slice(0, -1).join('.') : undefined;
55
+ const moduleNode = index.findModule(module);
56
+ const path = featureId ? featurePath(index.structure, featureId) : undefined;
57
+ const containerFeature = featureId ?? index.firstFeatureId(module);
58
+ return {
59
+ plan: {
60
+ kind: slice.kind === SliceKind.StateChange ? 'stateChange' : 'stateView',
61
+ module,
62
+ feature: containerFeature,
63
+ slice: target.slice,
64
+ ...slice.kind === SliceKind.StateChange ? {
65
+ command: slice.command ?? slice.id
66
+ } : {},
67
+ breadcrumb: [
68
+ moduleNode?.name ?? module,
69
+ ...path?.names ?? [],
70
+ slice.name
71
+ ]
72
+ },
73
+ problems: []
74
+ };
75
+ }
76
+ const moduleNode = index.findModule(target.module);
77
+ if (!moduleNode) return {
78
+ problems: [
79
+ error(PreviewProblemCode.TargetNotFound, `The module '${target.module}' is not in the application.`, target.module)
80
+ ]
81
+ };
82
+ if (target.feature === undefined) {
83
+ const first = index.firstFeatureId(target.module);
84
+ if (first === undefined) return {
85
+ problems: [
86
+ error(PreviewProblemCode.ModuleWithoutFeatures, `The module '${moduleNode.name}' has no feature to show.`, target.module)
87
+ ]
88
+ };
89
+ return {
90
+ plan: {
91
+ kind: 'module',
92
+ module: target.module,
93
+ feature: first,
94
+ breadcrumb: [
95
+ moduleNode.name,
96
+ ...featurePath(index.structure, first)?.names ?? []
97
+ ]
98
+ },
99
+ problems: []
100
+ };
101
+ }
102
+ const qualified = target.feature.startsWith(`${target.module}.`) ? target.feature : `${target.module}.${target.feature}`;
103
+ const path = featurePath(index.structure, qualified);
104
+ if (!path) return {
105
+ problems: [
106
+ error(PreviewProblemCode.TargetNotFound, `The feature '${qualified}' is not in the application.`, qualified)
107
+ ]
108
+ };
109
+ return {
110
+ plan: {
111
+ kind: 'feature',
112
+ module: target.module,
113
+ feature: qualified,
114
+ breadcrumb: [
115
+ moduleNode.name,
116
+ ...path.names
117
+ ]
118
+ },
119
+ problems: []
120
+ };
121
+ }
122
+
123
+ export { resolvePreviewPlan };
124
+ //# sourceMappingURL=resolvePreviewPlan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolvePreviewPlan.js","sources":["../../../preview-host/resolvePreviewPlan.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 { ApplicationStructure, FeatureNode, SliceKind } from '@cratis/scene.model';\nimport { ApplicationStructureIndex } from '@cratis/scene.engine';\nimport { PreviewTarget, isSliceTarget } from './PreviewTarget';\nimport { PreviewProblem, PreviewProblemCode, PreviewProblemSeverity } from './PreviewProblem';\n\n/** What a target resolved to in the application structure. */\nexport interface PreviewPlan {\n /** `module`, `feature`, `stateChange` or `stateView`. */\n kind: 'module' | 'feature' | 'stateChange' | 'stateView';\n\n /** The module the preview is in. */\n module: string;\n\n /** The qualified id of the feature whose screen is the page: the module's first feature, the feature itself, or the slice's feature. */\n feature?: string;\n\n /** The qualified id of the slice, for a slice target. */\n slice?: string;\n\n /** The command a State Change slice accepts. */\n command?: string;\n\n /** The display names from the module down to the target - what the preview strip shows as `Sales › Orders` (PRV7). */\n breadcrumb: string[];\n}\n\nexport interface PreviewPlanResult {\n plan?: PreviewPlan;\n problems: PreviewProblem[];\n}\n\nconst error = (code: PreviewProblemCode, message: string, nodeId?: string): PreviewProblem => ({ code, severity: PreviewProblemSeverity.Error, message, ...(nodeId === undefined ? {} : { nodeId }) });\n\n/** The feature a qualified id names, and the display names of the features above it, outermost first. */\nfunction featurePath(structure: ApplicationStructure, qualified: string): { feature: FeatureNode; names: string[] } | undefined {\n const [moduleId, ...rest] = qualified.split('.');\n let features = structure.modules.find(module => module.id === moduleId)?.features;\n const names: string[] = [];\n let found: FeatureNode | undefined;\n for (const id of rest) {\n found = features?.find(candidate => candidate.id === id);\n if (!found) return undefined;\n names.push(found.name);\n features = found.features;\n }\n\n return found ? { feature: found, names } : undefined;\n}\n\n/**\n * Resolves a preview target against the application structure (PRV3): a module previews its first feature, a feature itself,\n * a slice the page of the feature it belongs to with the slice itself opened (State Change) or isolated (State View).\n * A target that is not in the structure resolves to a problem, not to a blank screen.\n */\nexport function resolvePreviewPlan(structure: ApplicationStructure | ApplicationStructureIndex, target: PreviewTarget): PreviewPlanResult {\n const index = structure instanceof ApplicationStructureIndex ? structure : new ApplicationStructureIndex(structure);\n\n if (isSliceTarget(target)) {\n const slice = index.findSlice(target.slice);\n if (!slice) return { problems: [error(PreviewProblemCode.TargetNotFound, `The slice '${target.slice}' is not in the application.`, target.slice)] };\n if (slice.kind === SliceKind.Automation) {\n return { problems: [error(PreviewProblemCode.SliceNotPreviewable, `The slice '${target.slice}' is an automation: it reacts to events and has nothing to show.`, target.slice)] };\n }\n\n const segments = target.slice.split('.');\n const module = segments[0];\n const featureId = segments.length > 2 ? segments.slice(0, -1).join('.') : undefined;\n const moduleNode = index.findModule(module);\n const path = featureId ? featurePath(index.structure, featureId) : undefined;\n const containerFeature = featureId ?? index.firstFeatureId(module);\n return {\n plan: {\n kind: slice.kind === SliceKind.StateChange ? 'stateChange' : 'stateView',\n module,\n feature: containerFeature,\n slice: target.slice,\n ...(slice.kind === SliceKind.StateChange ? { command: slice.command ?? slice.id } : {}),\n breadcrumb: [moduleNode?.name ?? module, ...(path?.names ?? []), slice.name],\n },\n problems: [],\n };\n }\n\n const moduleNode = index.findModule(target.module);\n if (!moduleNode) return { problems: [error(PreviewProblemCode.TargetNotFound, `The module '${target.module}' is not in the application.`, target.module)] };\n\n if (target.feature === undefined) {\n const first = index.firstFeatureId(target.module);\n if (first === undefined) return { problems: [error(PreviewProblemCode.ModuleWithoutFeatures, `The module '${moduleNode.name}' has no feature to show.`, target.module)] };\n return { plan: { kind: 'module', module: target.module, feature: first, breadcrumb: [moduleNode.name, ...(featurePath(index.structure, first)?.names ?? [])] }, problems: [] };\n }\n\n const qualified = target.feature.startsWith(`${target.module}.`) ? target.feature : `${target.module}.${target.feature}`;\n const path = featurePath(index.structure, qualified);\n if (!path) return { problems: [error(PreviewProblemCode.TargetNotFound, `The feature '${qualified}' is not in the application.`, qualified)] };\n return { plan: { kind: 'feature', module: target.module, feature: qualified, breadcrumb: [moduleNode.name, ...path.names] }, problems: [] };\n}\n"],"names":["error","code","message","nodeId","severity","PreviewProblemSeverity","Error","undefined","featurePath","structure","qualified","moduleId","rest","split","features","modules","find","module","id","names","found","candidate","push","name","feature","resolvePreviewPlan","target","index","ApplicationStructureIndex","isSliceTarget","slice","findSlice","problems","PreviewProblemCode","TargetNotFound","kind","SliceKind","Automation","SliceNotPreviewable","segments","featureId","length","join","moduleNode","findModule","path","containerFeature","firstFeatureId","plan","StateChange","command","breadcrumb","first","ModuleWithoutFeatures","startsWith"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { SizeClass } from '@cratis/scene.model';
2
+ export declare function useSizeClass(): SizeClass;
3
+ //# sourceMappingURL=useSizeClass.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSizeClass.d.ts","sourceRoot":"","sources":["../../../preview-host/useSizeClass.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAQrD,wBAAgB,YAAY,IAAI,SAAS,CAUxC"}
@@ -0,0 +1,21 @@
1
+ import { useState, useEffect } from 'react';
2
+ import { computeSizeClass } from '@cratis/scene.engine';
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
+ * Tracks the browser window's {@link SizeClass}, recomputing whenever it resizes across a boundary the
8
+ * shared engine cares about. This is what lets a modeled `when width compact` override actually take
9
+ * effect on a narrow window instead of the arrangement engine's size-aware logic never being asked.
10
+ */ function useSizeClass() {
11
+ const [sizeClass, setSizeClass] = useState(()=>computeSizeClass(globalThis.innerWidth, globalThis.innerHeight));
12
+ useEffect(()=>{
13
+ const onResize = ()=>setSizeClass(computeSizeClass(globalThis.innerWidth, globalThis.innerHeight));
14
+ globalThis.addEventListener('resize', onResize);
15
+ return ()=>globalThis.removeEventListener('resize', onResize);
16
+ }, []);
17
+ return sizeClass;
18
+ }
19
+
20
+ export { useSizeClass };
21
+ //# sourceMappingURL=useSizeClass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSizeClass.js","sources":["../../../preview-host/useSizeClass.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 { useEffect, useState } from 'react';\nimport type { SizeClass } from '@cratis/scene.model';\nimport { computeSizeClass } from '@cratis/scene.engine';\n\n/**\n * Tracks the browser window's {@link SizeClass}, recomputing whenever it resizes across a boundary the\n * shared engine cares about. This is what lets a modeled `when width compact` override actually take\n * effect on a narrow window instead of the arrangement engine's size-aware logic never being asked.\n */\nexport function useSizeClass(): SizeClass {\n const [sizeClass, setSizeClass] = useState<SizeClass>(() => computeSizeClass(globalThis.innerWidth, globalThis.innerHeight));\n\n useEffect(() => {\n const onResize = () => setSizeClass(computeSizeClass(globalThis.innerWidth, globalThis.innerHeight));\n globalThis.addEventListener('resize', onResize);\n return () => globalThis.removeEventListener('resize', onResize);\n }, []);\n\n return sizeClass;\n}\n"],"names":["useSizeClass","sizeClass","setSizeClass","useState","computeSizeClass","globalThis","innerWidth","innerHeight","useEffect","onResize","addEventListener","removeEventListener"],"mappings":";;;AAAA;AACA;AAMA;;;;AAIC,IACM,SAASA,YAAAA,GAAAA;IACZ,MAAM,CAACC,SAAAA,EAAWC,YAAAA,CAAa,GAAGC,QAAAA,CAAoB,IAAMC,gBAAAA,CAAiBC,UAAAA,CAAWC,UAAU,EAAED,UAAAA,CAAWE,WAAW,CAAA,CAAA;IAE1HC,SAAAA,CAAU,IAAA;QACN,MAAMC,QAAAA,GAAW,IAAMP,YAAAA,CAAaE,gBAAAA,CAAiBC,WAAWC,UAAU,EAAED,WAAWE,WAAW,CAAA,CAAA;QAClGF,UAAAA,CAAWK,gBAAgB,CAAC,QAAA,EAAUD,QAAAA,CAAAA;AACtC,QAAA,OAAO,IAAMJ,UAAAA,CAAWM,mBAAmB,CAAC,QAAA,EAAUF,QAAAA,CAAAA;AAC1D,IAAA,CAAA,EAAG,EAAE,CAAA;IAEL,OAAOR,SAAAA;AACX;;"}