@loomwork/blueprint-runtime 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +8 -0
  3. package/README.md +83 -2
  4. package/dist/Blueprint.d.ts +14 -0
  5. package/dist/Blueprint.d.ts.map +1 -0
  6. package/dist/Blueprint.js +18 -0
  7. package/dist/Blueprint.js.map +1 -0
  8. package/dist/RendererRegistry.d.ts +9 -0
  9. package/dist/RendererRegistry.d.ts.map +1 -0
  10. package/dist/RendererRegistry.js +39 -0
  11. package/dist/RendererRegistry.js.map +1 -0
  12. package/dist/catalog.d.ts +129 -0
  13. package/dist/catalog.d.ts.map +1 -0
  14. package/dist/catalog.js +435 -0
  15. package/dist/catalog.js.map +1 -0
  16. package/dist/coverage.d.ts +18 -0
  17. package/dist/coverage.d.ts.map +1 -0
  18. package/dist/coverage.js +22 -0
  19. package/dist/coverage.js.map +1 -0
  20. package/dist/customWidget.d.ts +10 -0
  21. package/dist/customWidget.d.ts.map +1 -0
  22. package/dist/customWidget.js +34 -0
  23. package/dist/customWidget.js.map +1 -0
  24. package/dist/esm/Blueprint.js +15 -0
  25. package/dist/esm/Blueprint.js.map +1 -0
  26. package/dist/esm/RendererRegistry.js +35 -0
  27. package/dist/esm/RendererRegistry.js.map +1 -0
  28. package/dist/esm/catalog.js +430 -0
  29. package/dist/esm/catalog.js.map +1 -0
  30. package/dist/esm/coverage.js +19 -0
  31. package/dist/esm/coverage.js.map +1 -0
  32. package/dist/esm/customWidget.js +31 -0
  33. package/dist/esm/customWidget.js.map +1 -0
  34. package/dist/esm/identity.js +116 -0
  35. package/dist/esm/identity.js.map +1 -0
  36. package/dist/esm/index.js +15 -0
  37. package/dist/esm/index.js.map +1 -0
  38. package/dist/esm/irVersion.js +150 -0
  39. package/dist/esm/irVersion.js.map +1 -0
  40. package/dist/esm/layout.js +63 -0
  41. package/dist/esm/layout.js.map +1 -0
  42. package/dist/esm/normalize.js +115 -0
  43. package/dist/esm/normalize.js.map +1 -0
  44. package/dist/esm/pins.js +82 -0
  45. package/dist/esm/pins.js.map +1 -0
  46. package/dist/esm/traverseBlueprint.js +38 -0
  47. package/dist/esm/traverseBlueprint.js.map +1 -0
  48. package/dist/esm/traverseBlueprintAsync.js +48 -0
  49. package/dist/esm/traverseBlueprintAsync.js.map +1 -0
  50. package/dist/esm/types.js +2 -0
  51. package/dist/esm/types.js.map +1 -0
  52. package/dist/esm/widgetStatus.js +137 -0
  53. package/dist/esm/widgetStatus.js.map +1 -0
  54. package/dist/esm/widgets.js +105 -0
  55. package/dist/esm/widgets.js.map +1 -0
  56. package/dist/identity.d.ts +58 -0
  57. package/dist/identity.d.ts.map +1 -0
  58. package/dist/identity.js +122 -0
  59. package/dist/identity.js.map +1 -0
  60. package/dist/index.d.ts +24 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +61 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/irVersion.d.ts +23 -0
  65. package/dist/irVersion.d.ts.map +1 -0
  66. package/dist/irVersion.js +153 -0
  67. package/dist/irVersion.js.map +1 -0
  68. package/dist/layout.d.ts +57 -0
  69. package/dist/layout.d.ts.map +1 -0
  70. package/dist/layout.js +71 -0
  71. package/dist/layout.js.map +1 -0
  72. package/dist/normalize.d.ts +29 -0
  73. package/dist/normalize.d.ts.map +1 -0
  74. package/dist/normalize.js +126 -0
  75. package/dist/normalize.js.map +1 -0
  76. package/dist/pins.d.ts +27 -0
  77. package/dist/pins.d.ts.map +1 -0
  78. package/dist/pins.js +86 -0
  79. package/dist/pins.js.map +1 -0
  80. package/dist/traverseBlueprint.d.ts +27 -0
  81. package/dist/traverseBlueprint.d.ts.map +1 -0
  82. package/dist/traverseBlueprint.js +40 -0
  83. package/dist/traverseBlueprint.js.map +1 -0
  84. package/dist/traverseBlueprintAsync.d.ts +18 -0
  85. package/dist/traverseBlueprintAsync.d.ts.map +1 -0
  86. package/dist/traverseBlueprintAsync.js +51 -0
  87. package/dist/traverseBlueprintAsync.js.map +1 -0
  88. package/dist/types.d.ts +176 -0
  89. package/dist/types.d.ts.map +1 -0
  90. package/dist/types.js +3 -0
  91. package/dist/types.js.map +1 -0
  92. package/dist/widgetStatus.d.ts +66 -0
  93. package/dist/widgetStatus.d.ts.map +1 -0
  94. package/dist/widgetStatus.js +141 -0
  95. package/dist/widgetStatus.js.map +1 -0
  96. package/dist/widgets.d.ts +101 -0
  97. package/dist/widgets.d.ts.map +1 -0
  98. package/dist/widgets.js +115 -0
  99. package/dist/widgets.js.map +1 -0
  100. package/package.json +60 -3
  101. package/src/Blueprint.ts +28 -0
  102. package/src/RendererRegistry.ts +38 -0
  103. package/src/catalog.ts +638 -0
  104. package/src/coverage.ts +52 -0
  105. package/src/customWidget.ts +42 -0
  106. package/src/identity.ts +178 -0
  107. package/src/index.ts +84 -0
  108. package/src/irVersion.ts +195 -0
  109. package/src/layout.ts +105 -0
  110. package/src/normalize.ts +130 -0
  111. package/src/pins.ts +84 -0
  112. package/src/traverseBlueprint.bench.ts +47 -0
  113. package/src/traverseBlueprint.ts +94 -0
  114. package/src/traverseBlueprintAsync.ts +92 -0
  115. package/src/types.ts +195 -0
  116. package/src/widgetStatus.ts +231 -0
  117. package/src/widgets.ts +213 -0
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MetricCard = MetricCard;
4
+ exports.Timeline = Timeline;
5
+ exports.ApprovalCard = ApprovalCard;
6
+ exports.StatusBadge = StatusBadge;
7
+ exports.ProgressBar = ProgressBar;
8
+ exports.DataTable = DataTable;
9
+ exports.AlertCard = AlertCard;
10
+ exports.StreamingText = StreamingText;
11
+ // A derived id, used when the caller supplies none. It is an IDENTITY, not a
12
+ // content address: a 32-bit non-cryptographic hash, scoped to one blueprint.
13
+ // Never treat it as an audit anchor for "which view was this" — use a real digest
14
+ // (`contentAddress` in @loomwork/plugin-content) for that.
15
+ //
16
+ // Because it is derived from the props, it CHANGES when any prop changes. That is
17
+ // correct for a view that is authored once and wrong for one a composer revises,
18
+ // which is why every builder accepts an explicit `id`.
19
+ function stableId(kind, props) {
20
+ const str = kind + JSON.stringify(props, Object.keys(props).sort());
21
+ let hash = 0;
22
+ for (let i = 0; i < str.length; i++) {
23
+ hash = (Math.imul(31, hash) + str.charCodeAt(i)) | 0;
24
+ }
25
+ return `${kind}-${(hash >>> 0).toString(16)}`;
26
+ }
27
+ function MetricCard(props) {
28
+ const { title, id, ...rest } = props;
29
+ return {
30
+ _tag: "Widget",
31
+ id: id ?? stableId("MetricCard", props),
32
+ kind: "MetricCard",
33
+ title,
34
+ props: rest,
35
+ binding: props.binding,
36
+ };
37
+ }
38
+ function Timeline(props) {
39
+ const { title, id, ...rest } = props;
40
+ return {
41
+ _tag: "Widget",
42
+ id: id ?? stableId("Timeline", props),
43
+ kind: "Timeline",
44
+ ...(title !== undefined && { title }),
45
+ props: rest,
46
+ binding: props.binding,
47
+ };
48
+ }
49
+ function ApprovalCard(props) {
50
+ const { title, id, ...rest } = props;
51
+ return {
52
+ _tag: "Widget",
53
+ id: id ?? stableId("ApprovalCard", props),
54
+ kind: "ApprovalCard",
55
+ title,
56
+ props: rest,
57
+ binding: props.binding,
58
+ };
59
+ }
60
+ function StatusBadge(props) {
61
+ const { title, id, ...rest } = props;
62
+ return {
63
+ _tag: "Widget",
64
+ id: id ?? stableId("StatusBadge", props),
65
+ kind: "StatusBadge",
66
+ ...(title !== undefined && { title }),
67
+ props: rest,
68
+ binding: props.binding,
69
+ };
70
+ }
71
+ function ProgressBar(props) {
72
+ const { title, id, ...rest } = props;
73
+ return {
74
+ _tag: "Widget",
75
+ id: id ?? stableId("ProgressBar", props),
76
+ kind: "ProgressBar",
77
+ ...(title !== undefined && { title }),
78
+ props: rest,
79
+ binding: props.binding,
80
+ };
81
+ }
82
+ function DataTable(props) {
83
+ const { title, id, ...rest } = props;
84
+ return {
85
+ _tag: "Widget",
86
+ id: id ?? stableId("DataTable", props),
87
+ kind: "DataTable",
88
+ ...(title !== undefined && { title }),
89
+ props: rest,
90
+ binding: props.binding,
91
+ };
92
+ }
93
+ function AlertCard(props) {
94
+ const { title, id, ...rest } = props;
95
+ return {
96
+ _tag: "Widget",
97
+ id: id ?? stableId("AlertCard", props),
98
+ kind: "AlertCard",
99
+ ...(title !== undefined && { title }),
100
+ props: rest,
101
+ binding: props.binding,
102
+ };
103
+ }
104
+ function StreamingText(props) {
105
+ const { title, id, ...rest } = props;
106
+ return {
107
+ _tag: "Widget",
108
+ id: id ?? stableId("StreamingText", props),
109
+ kind: "StreamingText",
110
+ ...(title !== undefined && { title }),
111
+ props: rest,
112
+ binding: props.binding,
113
+ };
114
+ }
115
+ //# sourceMappingURL=widgets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widgets.js","sourceRoot":"","sources":["../src/widgets.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,63 @@
1
1
  {
2
2
  "name": "@loomwork/blueprint-runtime",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.0",
4
+ "description": "Schema-driven UI blueprint generation — pure JSON-serializable types",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "module": "./dist/esm/index.js",
8
+ "sideEffects": false,
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "require": "./dist/index.js",
13
+ "node": "./dist/index.js",
14
+ "import": "./dist/esm/index.js",
15
+ "default": "./dist/index.js"
16
+ }
17
+ },
18
+ "dependencies": {
19
+ "@loomwork/core": "^0.1.0",
20
+ "@loomwork/scheduler": "^0.1.0",
21
+ "@loomwork/classify": "^0.1.0"
22
+ },
23
+ "devDependencies": {
24
+ "@types/node": "^22.0.0",
25
+ "typescript": "^5.6.3",
26
+ "vitest": "^2.1.8"
27
+ },
28
+ "license": "Apache-2.0",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/chhetrisushil/loom.git",
32
+ "directory": "packages/blueprint-runtime"
33
+ },
34
+ "files": [
35
+ "dist",
36
+ "src",
37
+ "!src/**/*.test.ts",
38
+ "!src/**/*.test.tsx",
39
+ "!src/**/__tests__",
40
+ "!src/**/__fixtures__",
41
+ "!src/**/__snapshots__",
42
+ "!src/**/__golden__",
43
+ "LICENSE",
44
+ "NOTICE"
45
+ ],
46
+ "publishConfig": {
47
+ "access": "public",
48
+ "tag": "next"
49
+ },
50
+ "engines": {
51
+ "node": ">=20.0.0"
52
+ },
53
+ "scripts": {
54
+ "build": "tsc --build && rm -rf dist/esm && tsc -p tsconfig.esm.json",
55
+ "build:esm": "rm -rf dist/esm && tsc -p tsconfig.esm.json",
56
+ "dev": "tsc --build --watch",
57
+ "test": "vitest run",
58
+ "test:watch": "vitest",
59
+ "bench": "vitest bench --run",
60
+ "clean": "rm -rf dist tsconfig.tsbuildinfo",
61
+ "typecheck:tests": "tsc -p tsconfig.test.json"
62
+ }
6
63
  }
@@ -0,0 +1,28 @@
1
+ import { BLUEPRINT_IR_VERSION } from "./irVersion";
2
+ import type { Blueprint, Layout } from "./types";
3
+
4
+ export interface BlueprintConfig {
5
+ id: string;
6
+ title: string;
7
+ layout: Layout;
8
+ projections: string[];
9
+ /**
10
+ * ADR 0095 — the declared versions of the projections this view binds to, at composition.
11
+ * `projectionRuntime.pins()` is where they come from. See {@link Blueprint.projectionVersions}.
12
+ */
13
+ projectionVersions?: Readonly<Record<string, string>>;
14
+ }
15
+
16
+ export function blueprint$(config: BlueprintConfig): Blueprint {
17
+ return {
18
+ _tag: "Blueprint",
19
+ irVersion: BLUEPRINT_IR_VERSION,
20
+ id: config.id,
21
+ title: config.title,
22
+ layout: config.layout,
23
+ projections: config.projections,
24
+ ...(config.projectionVersions !== undefined && {
25
+ projectionVersions: config.projectionVersions,
26
+ }),
27
+ };
28
+ }
@@ -0,0 +1,38 @@
1
+ // Generic widget registry — framework-agnostic.
2
+ // TRenderer is narrowed by each framework adapter:
3
+ // React: RendererRegistry<React.FC<WidgetRendererProps>>
4
+ // Angular: RendererRegistry<Type<unknown>>
5
+ // DOM: RendererRegistry<(el: HTMLElement, props: WidgetRendererProps) => void>
6
+
7
+ export class RendererRegistry<TRenderer> {
8
+ private readonly renderers = new Map<string, TRenderer>();
9
+
10
+ register(kind: string, renderer: TRenderer): this {
11
+ this.renderers.set(kind, renderer);
12
+ return this;
13
+ }
14
+
15
+ get(kind: string): TRenderer | undefined {
16
+ return this.renderers.get(kind);
17
+ }
18
+
19
+ has(kind: string): boolean {
20
+ return this.renderers.has(kind);
21
+ }
22
+
23
+ kinds(): string[] {
24
+ return Array.from(this.renderers.keys());
25
+ }
26
+
27
+ // Returns a new registry that contains all renderers from both registries.
28
+ // Entries in `other` win on conflicts.
29
+ merge(other: RendererRegistry<TRenderer>): RendererRegistry<TRenderer> {
30
+ const merged = new RendererRegistry<TRenderer>();
31
+ for (const [kind, r] of this.renderers) merged.register(kind, r);
32
+ for (const kind of other.kinds()) {
33
+ const r = other.get(kind);
34
+ if (r !== undefined) merged.register(kind, r);
35
+ }
36
+ return merged;
37
+ }
38
+ }