@juo/blocks 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/dist/ExtensionRoot-CZyBNJZY.js +159 -0
  2. package/dist/block-VhmfGB3N.js +51 -0
  3. package/dist/block.d.ts +96 -0
  4. package/dist/block.d.ts.map +1 -0
  5. package/dist/bridge-DQsM97cH.js +490 -0
  6. package/dist/context.d.ts +76 -0
  7. package/dist/context.d.ts.map +1 -0
  8. package/dist/context.test.d.ts +2 -0
  9. package/dist/context.test.d.ts.map +1 -0
  10. package/dist/core.js +1163 -0
  11. package/dist/editor/bridge.d.ts +75 -0
  12. package/dist/editor/bridge.d.ts.map +1 -0
  13. package/dist/editor/bridge.test.d.ts +2 -0
  14. package/dist/editor/bridge.test.d.ts.map +1 -0
  15. package/dist/editor/components.d.ts +31 -0
  16. package/dist/editor/components.d.ts.map +1 -0
  17. package/dist/editor/handler.d.ts +10 -0
  18. package/dist/editor/handler.d.ts.map +1 -0
  19. package/dist/editor/main.d.ts +17 -0
  20. package/dist/editor/main.d.ts.map +1 -0
  21. package/dist/editor/messages.d.ts +233 -0
  22. package/dist/editor/messages.d.ts.map +1 -0
  23. package/dist/editor.js +711 -0
  24. package/dist/flows/MockWorkflowApiAdapter.d.ts +13 -0
  25. package/dist/flows/MockWorkflowApiAdapter.d.ts.map +1 -0
  26. package/dist/flows/WorkflowService.d.ts +175 -0
  27. package/dist/flows/WorkflowService.d.ts.map +1 -0
  28. package/dist/flows/__tests__/WorkflowService.test.d.ts +2 -0
  29. package/dist/flows/__tests__/WorkflowService.test.d.ts.map +1 -0
  30. package/dist/flows/__tests__/defaults.test.d.ts +2 -0
  31. package/dist/flows/__tests__/defaults.test.d.ts.map +1 -0
  32. package/dist/flows/__tests__/juo-workflow.test.d.ts +2 -0
  33. package/dist/flows/__tests__/juo-workflow.test.d.ts.map +1 -0
  34. package/dist/flows/__tests__/overlay-behavior.test.d.ts +2 -0
  35. package/dist/flows/__tests__/overlay-behavior.test.d.ts.map +1 -0
  36. package/dist/flows/__tests__/theme-state-surfaces.test.d.ts +2 -0
  37. package/dist/flows/__tests__/theme-state-surfaces.test.d.ts.map +1 -0
  38. package/dist/flows/defaults.d.ts +15 -0
  39. package/dist/flows/defaults.d.ts.map +1 -0
  40. package/dist/flows/index.d.ts +4 -0
  41. package/dist/flows/index.d.ts.map +1 -0
  42. package/dist/flows/juo-workflow.d.ts +48 -0
  43. package/dist/flows/juo-workflow.d.ts.map +1 -0
  44. package/dist/juo-workflow-RSrOuKUH.js +591 -0
  45. package/dist/main.d.ts +11 -0
  46. package/dist/main.d.ts.map +1 -0
  47. package/dist/preact/block.d.ts +21 -0
  48. package/dist/preact/block.d.ts.map +1 -0
  49. package/dist/preact/block.test.d.ts +2 -0
  50. package/dist/preact/block.test.d.ts.map +1 -0
  51. package/dist/preact/bridge.d.ts +11 -0
  52. package/dist/preact/bridge.d.ts.map +1 -0
  53. package/dist/preact/context.d.ts +31 -0
  54. package/dist/preact/context.d.ts.map +1 -0
  55. package/dist/preact/main.d.ts +11 -0
  56. package/dist/preact/main.d.ts.map +1 -0
  57. package/dist/preact/signals.d.ts +23 -0
  58. package/dist/preact/signals.d.ts.map +1 -0
  59. package/dist/preact.js +230 -0
  60. package/dist/react/block.d.ts +21 -0
  61. package/dist/react/block.d.ts.map +1 -0
  62. package/dist/react/block.test.d.ts +2 -0
  63. package/dist/react/block.test.d.ts.map +1 -0
  64. package/dist/react/bridge.d.ts +11 -0
  65. package/dist/react/bridge.d.ts.map +1 -0
  66. package/dist/react/context.d.ts +28 -0
  67. package/dist/react/context.d.ts.map +1 -0
  68. package/dist/react/main.d.ts +11 -0
  69. package/dist/react/main.d.ts.map +1 -0
  70. package/dist/react/signals.d.ts +23 -0
  71. package/dist/react/signals.d.ts.map +1 -0
  72. package/dist/react.js +205 -0
  73. package/dist/services/index.d.ts +4 -0
  74. package/dist/services/index.d.ts.map +1 -0
  75. package/dist/services/login/index.d.ts +23 -0
  76. package/dist/services/login/index.d.ts.map +1 -0
  77. package/dist/services/login/loginService.d.ts +82 -0
  78. package/dist/services/login/loginService.d.ts.map +1 -0
  79. package/dist/services/product/adapter.d.ts +20 -0
  80. package/dist/services/product/adapter.d.ts.map +1 -0
  81. package/dist/services/product/index.d.ts +5 -0
  82. package/dist/services/product/index.d.ts.map +1 -0
  83. package/dist/services/product/productService.d.ts +12 -0
  84. package/dist/services/product/productService.d.ts.map +1 -0
  85. package/dist/services/product/types.d.ts +32 -0
  86. package/dist/services/product/types.d.ts.map +1 -0
  87. package/dist/services/subscription/adapter.d.ts +49 -0
  88. package/dist/services/subscription/adapter.d.ts.map +1 -0
  89. package/dist/services/subscription/index.d.ts +5 -0
  90. package/dist/services/subscription/index.d.ts.map +1 -0
  91. package/dist/services/subscription/list.d.ts +22 -0
  92. package/dist/services/subscription/list.d.ts.map +1 -0
  93. package/dist/services/subscription/store.d.ts +30 -0
  94. package/dist/services/subscription/store.d.ts.map +1 -0
  95. package/dist/services/subscription/subscriptionService.d.ts +12 -0
  96. package/dist/services/subscription/subscriptionService.d.ts.map +1 -0
  97. package/dist/services/subscription/types.d.ts +76 -0
  98. package/dist/services/subscription/types.d.ts.map +1 -0
  99. package/dist/shared/block.d.ts +17 -0
  100. package/dist/shared/block.d.ts.map +1 -0
  101. package/dist/shared/context.d.ts +16 -0
  102. package/dist/shared/context.d.ts.map +1 -0
  103. package/dist/shared/signals.d.ts +17 -0
  104. package/dist/shared/signals.d.ts.map +1 -0
  105. package/dist/state.d.ts +81 -0
  106. package/dist/state.d.ts.map +1 -0
  107. package/dist/theme-state-BZplRS92.js +886 -0
  108. package/dist/theme-state.d.ts +85 -0
  109. package/dist/theme-state.d.ts.map +1 -0
  110. package/dist/theme-state.locales.test.d.ts +2 -0
  111. package/dist/theme-state.locales.test.d.ts.map +1 -0
  112. package/dist/translation.d.ts +14 -0
  113. package/dist/translation.d.ts.map +1 -0
  114. package/dist/translation.test.d.ts +2 -0
  115. package/dist/translation.test.d.ts.map +1 -0
  116. package/dist/utils/index.d.ts +32 -0
  117. package/dist/utils/index.d.ts.map +1 -0
  118. package/dist/utils/login.d.ts +11 -0
  119. package/dist/utils/login.d.ts.map +1 -0
  120. package/dist/utils/uuid.d.ts +2 -0
  121. package/dist/utils/uuid.d.ts.map +1 -0
  122. package/dist/vue/block.d.ts +7 -0
  123. package/dist/vue/block.d.ts.map +1 -0
  124. package/dist/vue/bridge.d.ts +11 -0
  125. package/dist/vue/bridge.d.ts.map +1 -0
  126. package/dist/vue/context.d.ts +24 -0
  127. package/dist/vue/context.d.ts.map +1 -0
  128. package/dist/vue/main.d.ts +6 -0
  129. package/dist/vue/main.d.ts.map +1 -0
  130. package/dist/vue/signals.d.ts +5 -0
  131. package/dist/vue/signals.d.ts.map +1 -0
  132. package/dist/vue/target.d.ts +2 -0
  133. package/dist/vue/target.d.ts.map +1 -0
  134. package/dist/vue/transform.d.ts +2 -0
  135. package/dist/vue/transform.d.ts.map +1 -0
  136. package/dist/vue.js +254 -0
  137. package/dist/web-components/Block.d.ts +17 -0
  138. package/dist/web-components/Block.d.ts.map +1 -0
  139. package/dist/web-components/Block.test.d.ts +2 -0
  140. package/dist/web-components/Block.test.d.ts.map +1 -0
  141. package/dist/web-components/ExtensionRoot.d.ts +29 -0
  142. package/dist/web-components/ExtensionRoot.d.ts.map +1 -0
  143. package/dist/web-components/editor/InlineText.d.ts +29 -0
  144. package/dist/web-components/editor/InlineText.d.ts.map +1 -0
  145. package/dist/web-components/editor/main.d.ts +2 -0
  146. package/dist/web-components/editor/main.d.ts.map +1 -0
  147. package/dist/web-components/runtime/InlineText.d.ts +6 -0
  148. package/dist/web-components/runtime/InlineText.d.ts.map +1 -0
  149. package/dist/web-components/runtime/main.d.ts +2 -0
  150. package/dist/web-components/runtime/main.d.ts.map +1 -0
  151. package/dist/web-components-editor.js +183 -0
  152. package/dist/web-components-runtime.js +55 -0
  153. package/package.json +62 -0
@@ -0,0 +1,591 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+ import { c as createContext, d, E, i as getDefinedBlocks, a as createBlockInstance, w, r as registerBlock, g as defineBlock, t as subscribeContext } from "./theme-state-BZplRS92.js";
5
+ import { a as createEditorBridge, e as createSelectBlockMessage } from "./bridge-DQsM97cH.js";
6
+ const TranslationContext = createContext("translation");
7
+ function toStringRecord(input) {
8
+ if (input == null) return {};
9
+ return Object.fromEntries(
10
+ Object.entries(input).filter(([, value]) => typeof value === "string")
11
+ );
12
+ }
13
+ function createTranslationService(locales, options = {}) {
14
+ const loadedThemeDefaults = d({});
15
+ if (options.loadDefaultTranslations) {
16
+ let loadVersion = 0;
17
+ E(() => {
18
+ const locale = locales.locale.value;
19
+ const currentVersion = ++loadVersion;
20
+ void options.loadDefaultTranslations(locale).then((result) => toStringRecord(result)).catch(() => ({})).then((result) => {
21
+ if (currentVersion !== loadVersion) return;
22
+ loadedThemeDefaults.value = result;
23
+ });
24
+ });
25
+ }
26
+ return {
27
+ locale: locales.locale,
28
+ resolve(blockType, blockId, key) {
29
+ var _a, _b, _c;
30
+ const data = locales.catalogs.value;
31
+ const themeDefault = loadedThemeDefaults.value[key] ?? (data == null ? void 0 : data.theme.defaults[key]);
32
+ if (data == null) {
33
+ return themeDefault ?? key;
34
+ }
35
+ if (blockId && ((_a = data.blocks.overrides[blockId]) == null ? void 0 : _a[key]) !== void 0) {
36
+ return data.blocks.overrides[blockId][key];
37
+ }
38
+ const blockDefault = blockType != null ? (_b = data.blocks.defaults[blockType]) == null ? void 0 : _b[key] : void 0;
39
+ const mode = (blockType != null ? (_c = data.blocks.modes[blockType]) == null ? void 0 : _c[key] : void 0) ?? "override";
40
+ if (blockDefault !== void 0 && mode === "override") {
41
+ return blockDefault;
42
+ }
43
+ if (data.theme.overrides[key] !== void 0) {
44
+ return data.theme.overrides[key];
45
+ }
46
+ if (themeDefault !== void 0) {
47
+ return themeDefault;
48
+ }
49
+ if (blockDefault !== void 0) {
50
+ return blockDefault;
51
+ }
52
+ return key;
53
+ }
54
+ };
55
+ }
56
+ function getDefaultBlockForAction(actionType, actionConfig, blockId) {
57
+ const blockName = `action:${actionType}`;
58
+ const definedBlocks = getDefinedBlocks();
59
+ const exists = definedBlocks.some((b) => b.name === blockName);
60
+ if (!exists) {
61
+ throw new Error(
62
+ `No default block registered for action type "${actionType}". Expected a block named "${blockName}" to be registered in blocks-extensions.`
63
+ );
64
+ }
65
+ return createBlockInstance(blockName, { props: actionConfig, id: blockId });
66
+ }
67
+ function hasDefaultBlockForAction(actionType) {
68
+ const blockName = `action:${actionType}`;
69
+ return getDefinedBlocks().some((b) => b.name === blockName);
70
+ }
71
+ const WorkflowServiceContext = createContext("services/workflow");
72
+ function createWorkflowApiAdapter(sdk) {
73
+ return {
74
+ async start(flowType, context, workflowId, dryRun) {
75
+ const { data } = await sdk.post("/customer/v1/workflows/start", {
76
+ flowType,
77
+ context,
78
+ ...workflowId ? { workflowId } : {},
79
+ ...dryRun ? { dryRun: true } : {}
80
+ });
81
+ return data;
82
+ },
83
+ async respond(runId, interactionId, responseType, responseData, expectedRunVersion, eventId) {
84
+ const { data } = await sdk.post(
85
+ "/customer/v1/workflows/{runId}/respond",
86
+ {
87
+ runId,
88
+ interactionId,
89
+ responseType,
90
+ responseData,
91
+ expectedRunVersion,
92
+ eventId
93
+ }
94
+ );
95
+ return data;
96
+ },
97
+ async getState(runId) {
98
+ const { data } = await sdk.get("/customer/v1/workflows/{runId}", {
99
+ runId
100
+ });
101
+ return data;
102
+ },
103
+ async cancel(runId) {
104
+ const { data } = await sdk.post("/customer/v1/workflows/{runId}/cancel", {
105
+ runId
106
+ });
107
+ return data;
108
+ }
109
+ };
110
+ }
111
+ function createWorkflowService(deps) {
112
+ const { api } = deps;
113
+ const editor = createEditorBridge();
114
+ const urlParams = typeof window !== "undefined" ? new URLSearchParams(window.location.search) : null;
115
+ const previewWorkflowTrigger = (urlParams == null ? void 0 : urlParams.get("trigger")) ?? null;
116
+ const previewStepId = (urlParams == null ? void 0 : urlParams.get("step-id")) ?? null;
117
+ const previewWorkflowId = (urlParams == null ? void 0 : urlParams.get("workflow-id")) ?? null;
118
+ const isEditorMode = editor.isEditorMode || previewWorkflowTrigger !== null;
119
+ const _state = d({
120
+ status: "idle",
121
+ flowType: null,
122
+ workflowId: null,
123
+ workflowVersion: null,
124
+ runId: null,
125
+ runVersion: null,
126
+ currentStepId: null,
127
+ currentInteraction: null,
128
+ error: null,
129
+ result: null,
130
+ flowParams: null,
131
+ invalidatedResources: [],
132
+ outcome: null,
133
+ completionData: null,
134
+ dryRun: null
135
+ });
136
+ const _backendInteractionId = d(null);
137
+ const _registeredRootBlocks = /* @__PURE__ */ new Set();
138
+ const isActive = w(() => _state.value.status === "active");
139
+ const isLoading = w(() => _state.value.status === "loading");
140
+ const isCompleted = w(() => _state.value.status === "completed");
141
+ const hasError = w(() => _state.value.status === "error");
142
+ const currentInteraction = w(() => _state.value.currentInteraction);
143
+ const canRespond = w(() => {
144
+ const interaction = _state.value.currentInteraction;
145
+ const backendId = _backendInteractionId.value;
146
+ if (!interaction || !backendId) return false;
147
+ return interaction.interactionId === backendId;
148
+ });
149
+ const currentStepInfo = w(() => {
150
+ const interaction = _state.value.currentInteraction;
151
+ if (!interaction) return null;
152
+ const actionConfig = deps.shopCurrencyCode ? { ...interaction.actionConfig, currency: deps.shopCurrencyCode } : interaction.actionConfig;
153
+ return {
154
+ interactionId: interaction.interactionId,
155
+ stepId: interaction.stepId,
156
+ actionType: interaction.actionType,
157
+ actionConfig,
158
+ availableResponses: interaction.availableResponses
159
+ };
160
+ });
161
+ function updateState(updates) {
162
+ _state.value = { ..._state.value, ...updates };
163
+ }
164
+ function hashString(value) {
165
+ let hash = 2166136261;
166
+ for (let index = 0; index < value.length; index += 1) {
167
+ hash ^= value.charCodeAt(index);
168
+ hash = Math.imul(hash, 16777619);
169
+ }
170
+ return (hash >>> 0).toString(36);
171
+ }
172
+ function shortenId(value, slugLength = 6) {
173
+ const compact = value.toLowerCase().replace(/[^a-z0-9]/g, "");
174
+ const slug = (compact || "id").slice(0, slugLength);
175
+ return `${slug}-${hashString(value)}`;
176
+ }
177
+ function createStableStepBlockId(workflowId, stepId) {
178
+ return `wf-${shortenId(workflowId)}-${shortenId(stepId)}`;
179
+ }
180
+ function handleFlowResponse(data) {
181
+ var _a, _b, _c, _d, _e, _f;
182
+ const mergedInvalidated = [
183
+ ..._state.value.invalidatedResources,
184
+ ...data.invalidatedResources ?? []
185
+ ];
186
+ if (data.status === "waiting_interaction") {
187
+ const currentStepId = ((_a = data.pendingInteraction) == null ? void 0 : _a.stepId) ?? (isEditorMode ? (_c = (_b = data.interactiveSteps) == null ? void 0 : _b[0]) == null ? void 0 : _c.stepId : null);
188
+ _backendInteractionId.value = ((_d = data.pendingInteraction) == null ? void 0 : _d.interactionId) ?? null;
189
+ updateState({
190
+ status: "active",
191
+ workflowId: data.workflowId,
192
+ workflowVersion: data.workflowVersion,
193
+ runId: data.runId,
194
+ runVersion: data.runVersion,
195
+ currentStepId,
196
+ currentInteraction: data.pendingInteraction,
197
+ invalidatedResources: mergedInvalidated,
198
+ outcome: null
199
+ });
200
+ if (editor.isEditorMode) {
201
+ const overlayBlocks = deps.themeState.overlay.blocks.value;
202
+ const rootBlock = overlayBlocks[0];
203
+ const stepSlot = currentStepId ? (_e = rootBlock == null ? void 0 : rootBlock.slots) == null ? void 0 : _e[currentStepId] : null;
204
+ const stepBlock = Array.isArray(stepSlot) ? stepSlot[0] : null;
205
+ const blockId = stepBlock && typeof stepBlock === "object" && "id" in stepBlock ? stepBlock.id : null;
206
+ if (blockId) {
207
+ editor.sendMessage(
208
+ createSelectBlockMessage({ blockId }, blockId)
209
+ );
210
+ }
211
+ }
212
+ } else if (data.status === "completed") {
213
+ _backendInteractionId.value = null;
214
+ updateState({
215
+ status: "completed",
216
+ currentStepId: null,
217
+ currentInteraction: null,
218
+ runVersion: data.runVersion,
219
+ result: data.result || null,
220
+ invalidatedResources: mergedInvalidated,
221
+ outcome: data.outcome || null,
222
+ completionData: data.completionData || null
223
+ });
224
+ } else if (data.status === "failed") {
225
+ _backendInteractionId.value = null;
226
+ handleError(new Error(((_f = data.error) == null ? void 0 : _f.message) || "Flow failed"));
227
+ } else if (data.status === "cancelled") {
228
+ _backendInteractionId.value = null;
229
+ updateState({
230
+ status: "idle",
231
+ flowType: null,
232
+ workflowId: null,
233
+ workflowVersion: null,
234
+ runId: null,
235
+ runVersion: null,
236
+ currentStepId: null,
237
+ currentInteraction: null,
238
+ error: null,
239
+ result: null,
240
+ invalidatedResources: [],
241
+ outcome: null,
242
+ completionData: null
243
+ });
244
+ }
245
+ }
246
+ function handleError(error) {
247
+ const message = error instanceof Error ? error.message : "Unknown error";
248
+ updateState({
249
+ status: "error",
250
+ error: message
251
+ });
252
+ }
253
+ function maybeApplyPreviewStep(flowType, data) {
254
+ var _a;
255
+ if (!previewWorkflowTrigger) return;
256
+ if (flowType !== previewWorkflowTrigger) return;
257
+ if (data.status !== "waiting_interaction") return;
258
+ const step = (_a = data.interactiveSteps) == null ? void 0 : _a.find(
259
+ (interactiveStep) => interactiveStep.stepId === previewStepId
260
+ );
261
+ if (!step) return;
262
+ updateState({
263
+ currentStepId: step.stepId,
264
+ currentInteraction: {
265
+ interactionId: `preview-${data.runId}-${step.stepId}`,
266
+ stepId: step.stepId,
267
+ actionType: step.actionType,
268
+ actionBehavior: "input",
269
+ actionConfig: step.actionConfig,
270
+ availableResponses: step.availableResponses,
271
+ presentedAt: /* @__PURE__ */ new Date()
272
+ }
273
+ });
274
+ }
275
+ function initWorkflowRootBlock(data) {
276
+ if (_registeredRootBlocks.has(data.workflowId)) {
277
+ return;
278
+ }
279
+ const allSteps = data.interactiveSteps ?? (data.pendingInteraction ? [
280
+ {
281
+ stepId: data.pendingInteraction.stepId,
282
+ actionType: data.pendingInteraction.actionType,
283
+ actionConfig: data.pendingInteraction.actionConfig,
284
+ availableResponses: data.pendingInteraction.availableResponses
285
+ }
286
+ ] : []);
287
+ const slotProperties = {};
288
+ for (const step of allSteps) {
289
+ slotProperties[step.stepId] = {};
290
+ }
291
+ const presets = {};
292
+ for (const step of allSteps) {
293
+ presets[step.stepId] = {
294
+ label: step.stepId,
295
+ description: step.actionType,
296
+ state: step.stepId,
297
+ // @ts-expect-error Untyped
298
+ context: step
299
+ };
300
+ }
301
+ registerBlock(
302
+ defineBlock(`workflow:${data.workflowId}`, {
303
+ group: "workflow",
304
+ schema: {
305
+ type: "object",
306
+ properties: {
307
+ props: { type: "object" },
308
+ slots: {
309
+ type: "object",
310
+ properties: slotProperties
311
+ }
312
+ },
313
+ required: ["props", "slots"],
314
+ additionalProperties: true
315
+ },
316
+ initialValue: () => ({
317
+ props: {},
318
+ slots: Object.fromEntries(
319
+ allSteps.map((step) => [
320
+ step.stepId,
321
+ [
322
+ getDefaultBlockForAction(
323
+ step.actionType,
324
+ step.actionConfig,
325
+ createStableStepBlockId(data.workflowId, step.stepId)
326
+ )
327
+ ]
328
+ ])
329
+ )
330
+ }),
331
+ presets,
332
+ renderer() {
333
+ return null;
334
+ }
335
+ })
336
+ );
337
+ _registeredRootBlocks.add(data.workflowId);
338
+ }
339
+ async function initWorkflowState(data) {
340
+ const { blocks } = await deps.themeState.resolve(
341
+ "overlay",
342
+ data.workflowId,
343
+ `workflow:${data.workflowId}`
344
+ );
345
+ if (blocks.length === 0) return;
346
+ editor.onBlockPresetChange(blocks[0].id, (preset) => {
347
+ if (!preset) {
348
+ return;
349
+ }
350
+ updateState({
351
+ // @ts-expect-error Untyped
352
+ currentStepId: preset.state,
353
+ // @ts-expect-error Untyped
354
+ currentInteraction: { ...preset == null ? void 0 : preset.context }
355
+ });
356
+ });
357
+ }
358
+ const service = {
359
+ // State signals (readonly)
360
+ state: _state,
361
+ /** True when the portal is running inside the Blocks Editor (editorMode dep
362
+ * or ?trigger=... URL param). Consumers use this to suppress auto-start. */
363
+ isPreviewMode: isEditorMode,
364
+ // Computed signals
365
+ isActive,
366
+ isLoading,
367
+ isCompleted,
368
+ hasError,
369
+ canRespond,
370
+ currentInteraction,
371
+ currentStepInfo,
372
+ // Methods
373
+ async startFlow(flowType, context, workflowId) {
374
+ const isDryRun = isEditorMode;
375
+ updateState({
376
+ status: "loading",
377
+ error: null,
378
+ flowParams: context,
379
+ flowType,
380
+ dryRun: isDryRun
381
+ });
382
+ try {
383
+ const data = await api.start(
384
+ flowType,
385
+ context,
386
+ workflowId,
387
+ isDryRun || void 0
388
+ );
389
+ if (data.status === "no_workflow") {
390
+ service.reset();
391
+ return;
392
+ }
393
+ if (data.status === "completed_silently") {
394
+ updateState({
395
+ status: "completed",
396
+ currentStepId: null,
397
+ currentInteraction: null,
398
+ result: null,
399
+ invalidatedResources: data.invalidatedResources ?? [],
400
+ outcome: data.outcome || null,
401
+ completionData: data.completionData || null
402
+ });
403
+ return;
404
+ }
405
+ initWorkflowRootBlock(data);
406
+ await initWorkflowState(data);
407
+ handleFlowResponse(data);
408
+ maybeApplyPreviewStep(flowType, data);
409
+ } catch (error) {
410
+ handleError(error);
411
+ }
412
+ },
413
+ async respond(responseType, responseData) {
414
+ const { runId, runVersion, currentInteraction: currentInteraction2 } = _state.value;
415
+ if (!runId || !currentInteraction2) {
416
+ throw new Error("No active interaction to respond to");
417
+ }
418
+ updateState({ status: "loading" });
419
+ try {
420
+ const data = await api.respond(
421
+ runId,
422
+ currentInteraction2.interactionId,
423
+ responseType,
424
+ responseData,
425
+ runVersion ?? void 0
426
+ );
427
+ handleFlowResponse(data);
428
+ } catch (error) {
429
+ handleError(error);
430
+ }
431
+ },
432
+ async cancel() {
433
+ const { runId, status } = _state.value;
434
+ const isTerminal = status === "completed" || status === "error";
435
+ if (runId && !isTerminal) {
436
+ try {
437
+ const data = await api.cancel(runId);
438
+ if (data.outcome) {
439
+ updateState({
440
+ status: "completed",
441
+ flowType: null,
442
+ workflowId: null,
443
+ workflowVersion: null,
444
+ runId: null,
445
+ runVersion: null,
446
+ currentStepId: null,
447
+ currentInteraction: null,
448
+ error: null,
449
+ result: null,
450
+ flowParams: null,
451
+ invalidatedResources: data.invalidatedResources ?? [],
452
+ outcome: data.outcome || null,
453
+ dryRun: null
454
+ });
455
+ return;
456
+ }
457
+ } catch {
458
+ }
459
+ }
460
+ service.reset();
461
+ },
462
+ reset() {
463
+ _backendInteractionId.value = null;
464
+ updateState({
465
+ status: "idle",
466
+ flowType: null,
467
+ workflowId: null,
468
+ workflowVersion: null,
469
+ runId: null,
470
+ runVersion: null,
471
+ currentStepId: null,
472
+ currentInteraction: null,
473
+ error: null,
474
+ result: null,
475
+ flowParams: null,
476
+ invalidatedResources: [],
477
+ outcome: null,
478
+ completionData: null
479
+ });
480
+ },
481
+ async refresh() {
482
+ const { runId } = _state.value;
483
+ if (!runId) return;
484
+ try {
485
+ const data = await api.getState(runId);
486
+ handleFlowResponse(data);
487
+ } catch (error) {
488
+ handleError(error);
489
+ }
490
+ }
491
+ };
492
+ if (previewWorkflowTrigger) {
493
+ void service.startFlow(
494
+ previewWorkflowTrigger,
495
+ {},
496
+ previewWorkflowId ?? void 0
497
+ );
498
+ }
499
+ return service;
500
+ }
501
+ class JuoWorkflowElement extends HTMLElement {
502
+ constructor() {
503
+ super(...arguments);
504
+ __publicField(this, "workflowService", null);
505
+ __publicField(this, "unsubscribeContext", null);
506
+ __publicField(this, "unsubscribeEffect", null);
507
+ /** Tracks which step is currently mounted to avoid unnecessary DOM teardown. */
508
+ __publicField(this, "renderedStepId", null);
509
+ /**
510
+ * Optional function to wrap rendered content (step blocks).
511
+ * Must be set before workflow becomes active for correct behavior.
512
+ */
513
+ __publicField(this, "blockWrapper", null);
514
+ }
515
+ connectedCallback() {
516
+ this.style.display = "contents";
517
+ this.unsubscribeContext = subscribeContext(
518
+ this,
519
+ WorkflowServiceContext,
520
+ (service) => {
521
+ this.workflowService = service;
522
+ this.setupSubscription();
523
+ }
524
+ );
525
+ }
526
+ disconnectedCallback() {
527
+ var _a, _b;
528
+ (_a = this.unsubscribeContext) == null ? void 0 : _a.call(this);
529
+ (_b = this.unsubscribeEffect) == null ? void 0 : _b.call(this);
530
+ this.unsubscribeContext = null;
531
+ this.unsubscribeEffect = null;
532
+ this.renderedStepId = null;
533
+ }
534
+ setupSubscription() {
535
+ var _a;
536
+ if (!this.workflowService) return;
537
+ (_a = this.unsubscribeEffect) == null ? void 0 : _a.call(this);
538
+ this.unsubscribeEffect = E(() => {
539
+ var _a2, _b;
540
+ const status = ((_a2 = this.workflowService) == null ? void 0 : _a2.state.value.status) ?? "idle";
541
+ const stepInfo = (_b = this.workflowService) == null ? void 0 : _b.currentStepInfo.value;
542
+ const stepId = (stepInfo == null ? void 0 : stepInfo.stepId) ?? null;
543
+ queueMicrotask(() => {
544
+ if (this.isConnected) {
545
+ this.render(status, stepId);
546
+ }
547
+ });
548
+ });
549
+ }
550
+ render(status, stepId) {
551
+ var _a;
552
+ if ((status === "active" || status === "loading") && stepId) {
553
+ if (this.renderedStepId !== stepId) {
554
+ this.innerHTML = "";
555
+ this.renderedStepId = stepId;
556
+ const extensionRoot = document.createElement(
557
+ "juo-extension-root"
558
+ );
559
+ extensionRoot.setAttribute("surface", "overlay");
560
+ extensionRoot.setAttribute("name", stepId);
561
+ extensionRoot.blockWrapper = this.blockWrapper;
562
+ this.appendChild(extensionRoot);
563
+ }
564
+ return;
565
+ }
566
+ this.innerHTML = "";
567
+ this.renderedStepId = null;
568
+ if (status === "error") {
569
+ const error = ((_a = this.workflowService) == null ? void 0 : _a.state.value.error) ?? "Unknown error";
570
+ this.dispatchEvent(
571
+ new CustomEvent("juo-workflow-error", {
572
+ bubbles: true,
573
+ composed: true,
574
+ detail: { error }
575
+ })
576
+ );
577
+ }
578
+ }
579
+ }
580
+ if (typeof customElements !== "undefined" && !customElements.get("juo-workflow")) {
581
+ customElements.define("juo-workflow", JuoWorkflowElement);
582
+ }
583
+ export {
584
+ TranslationContext as T,
585
+ WorkflowServiceContext as W,
586
+ createWorkflowService as a,
587
+ createWorkflowApiAdapter as b,
588
+ createTranslationService as c,
589
+ getDefaultBlockForAction as g,
590
+ hasDefaultBlockForAction as h
591
+ };
package/dist/main.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ export type { Block, BlockInstance, BlockDefinition, BlockLocaleFile, BlockRenderer, BlockPreset, BlockPresets, } from './block';
2
+ export { createBlockInstance, createBlockInstanceFromJSON, createBlockInstanceFromObject, createCeRenderer, defineBlock, defineBlockRuntime, getDefinedBlocks, withWrapper, registerBlock, SelectedBlockContext, createSelectedBlock, BlockWrapperEvent, serializeBlocks, onRegisterBlock, } from './block';
3
+ export { ThemeStateContext, createThemeState, indexOverrides, type TranslationCatalogs, type TranslationMode, type TranslationScope, type TranslationOverride, type ThemeLocaleState, type ThemeState, type ThemeSurface, type ThemeSurfaceState, type GlobalStyles, type GlobalStyleColors, type ThemeType, DEFAULT_GLOBAL_STYLES, } from './theme-state';
4
+ export { TranslationContext, createTranslationService, type TranslationServiceOptions, type TranslationService, } from './translation';
5
+ export { ContextRequestEvent, ContextProvideEvent, type ContextCallback, createContext, injectContext, provideContext, subscribeContext, type ContextType, type UnknownContext, } from './context';
6
+ export { StateContext, createState } from './state';
7
+ export * from './utils';
8
+ export * from './services';
9
+ export * from './flows';
10
+ export { Signal, signal, effect, computed, untracked, } from '@preact/signals-core';
11
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,KAAK,EACL,aAAa,EACb,eAAe,EACf,eAAe,EACf,aAAa,EACb,WAAW,EACX,YAAY,GACb,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,mBAAmB,EACnB,2BAA2B,EAC3B,6BAA6B,EAC7B,gBAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EACf,eAAe,GAChB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,GACxB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,eAAe,EACpB,aAAa,EACb,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,KAAK,WAAW,EAChB,KAAK,cAAc,GACpB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEpD,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AAExB,OAAO,EACL,MAAM,EACN,MAAM,EACN,MAAM,EACN,QAAQ,EACR,SAAS,GACV,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { ComponentType } from 'preact';
2
+ import { BlockInstance } from '../main.ts';
3
+ /**
4
+ * Creates a block renderer for Preact components
5
+ *
6
+ * @param component - Preact component to render
7
+ * @returns A block renderer function
8
+ */
9
+ export declare function createPreactRenderer<P = any>(component: ComponentType<P>): (block: BlockInstance) => HTMLElement;
10
+ /**
11
+ * Creates a custom element renderer for Preact components
12
+ *
13
+ * @param name - Custom element name
14
+ * @param component - Preact component to render
15
+ * @param options - Renderer options
16
+ * @returns A block renderer function
17
+ */
18
+ export declare function createPreactCeRenderer<P = any>(name: string, component: ComponentType<P>, { shadowRoot }?: {
19
+ shadowRoot?: boolean;
20
+ }): (block: BlockInstance) => HTMLElement;
21
+ //# sourceMappingURL=block.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block.d.ts","sourceRoot":"","sources":["../../src/preact/block.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAqC,KAAK,aAAa,EAAE,MAAM,QAAQ,CAAC;AAE/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAyBjD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,GAAG,GAAG,EAC1C,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,GAC1B,CAAC,KAAK,EAAE,aAAa,KAAK,WAAW,CAgCvC;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,GAAG,GAAG,EAC5C,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,EAC3B,EAAE,UAAiB,EAAE,GAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,GACnD,CAAC,KAAK,EAAE,aAAa,KAAK,WAAW,CAoEvC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=block.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block.test.d.ts","sourceRoot":"","sources":["../../src/preact/block.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ import { PresetData, ExtractPresetState, ExtractPresetContext } from '../editor/bridge';
2
+ type PresetChangeCallback<TPresets> = (preset: PresetData<ExtractPresetState<TPresets>, ExtractPresetContext<TPresets>> | null) => void;
3
+ export interface UseBridgeOptions<TPresets = unknown> {
4
+ onPresetChange: PresetChangeCallback<TPresets>;
5
+ }
6
+ export interface BlockBridgeAPI {
7
+ readonly isEditorMode: boolean;
8
+ }
9
+ export declare function useBridge<TPresets = unknown>(options: UseBridgeOptions<TPresets>): BlockBridgeAPI;
10
+ export {};
11
+ //# sourceMappingURL=bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../src/preact/bridge.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EAC1B,MAAM,kBAAkB,CAAC;AAU1B,KAAK,oBAAoB,CAAC,QAAQ,IAAI,CACpC,MAAM,EAAE,UAAU,CAChB,kBAAkB,CAAC,QAAQ,CAAC,EAC5B,oBAAoB,CAAC,QAAQ,CAAC,CAC/B,GAAG,IAAI,KACL,IAAI,CAAC;AAEV,MAAM,WAAW,gBAAgB,CAAC,QAAQ,GAAG,OAAO;IAClD,cAAc,EAAE,oBAAoB,CAAC,QAAQ,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;CAChC;AAED,wBAAgB,SAAS,CAAC,QAAQ,GAAG,OAAO,EAC1C,OAAO,EAAE,gBAAgB,CAAC,QAAQ,CAAC,GAClC,cAAc,CAiChB"}
@@ -0,0 +1,31 @@
1
+ import { ComponentChildren } from 'preact';
2
+ import { ContextType, UnknownContext } from '../main.ts';
3
+ import { Wrap } from '../shared/context';
4
+ /**
5
+ * Context Provider component for Preact
6
+ *
7
+ * Provides the DOM element reference needed for Blocks context operations.
8
+ */
9
+ export declare function ContextProvider({ children }: {
10
+ children: ComponentChildren;
11
+ }): import('preact').VNode<import('preact').Attributes & {
12
+ value: HTMLElement | null;
13
+ children?: ComponentChildren;
14
+ }>;
15
+ /**
16
+ * Hook to provide context value in Preact components
17
+ *
18
+ * @param context - The context to provide
19
+ * @param init - The initial value for the context
20
+ */
21
+ export declare function useProvideContext<C extends UnknownContext>(context: C, init: ContextType<C>): void;
22
+ /**
23
+ * Hook to inject context value in Preact components
24
+ *
25
+ * @param context - The context to inject
26
+ * @returns The context value, with signals automatically converted to Preact state
27
+ */
28
+ export declare function useContext<C extends UnknownContext>(context: C): Wrap<ContextType<C>>;
29
+ export declare function useBlockId(): string | null;
30
+ export type { Wrap } from '../shared/context';
31
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/preact/context.ts"],"names":[],"mappings":"AASA,OAAO,EAAK,KAAK,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AACnD,OAAO,EACL,WAAW,EAGX,cAAc,EACf,MAAM,aAAa,CAAC;AAErB,OAAO,EAAe,KAAK,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAI3D;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,iBAAiB,CAAA;CAAE;;;GAiB5E;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,cAAc,EACxD,OAAO,EAAE,CAAC,EACV,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,GACnB,IAAI,CAON;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,cAAc,EACjD,OAAO,EAAE,CAAC,GACT,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAOtB;AAED,wBAAgB,UAAU,IAAI,MAAM,GAAG,IAAI,CAU1C;AAED,YAAY,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC"}