@mulmoclaude/mulmoscript-plugin 4.4.0 → 4.5.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 (45) hide show
  1. package/dist/contract-BHqxMUWm.cjs +82 -0
  2. package/dist/contract-BHqxMUWm.cjs.map +1 -0
  3. package/dist/contract-BnIl6w_f.js +53 -0
  4. package/dist/contract-BnIl6w_f.js.map +1 -0
  5. package/dist/core/contract.d.ts +80 -6
  6. package/dist/core/contract.d.ts.map +1 -1
  7. package/dist/core/definition.d.ts.map +1 -1
  8. package/dist/core/paths.d.ts +41 -0
  9. package/dist/core/paths.d.ts.map +1 -1
  10. package/dist/index.cjs +1 -1
  11. package/dist/index.js +1 -1
  12. package/dist/{plugin-BOq5YkTl.cjs → plugin-C5JC2lNR.cjs} +51 -1
  13. package/dist/plugin-C5JC2lNR.cjs.map +1 -0
  14. package/dist/{plugin-CAhxJ5WM.js → plugin-Jo8iGv4K.js} +40 -2
  15. package/dist/plugin-Jo8iGv4K.js.map +1 -0
  16. package/dist/server/dispatch.d.ts +0 -6
  17. package/dist/server/dispatch.d.ts.map +1 -1
  18. package/dist/server/ops.d.ts +29 -18
  19. package/dist/server/ops.d.ts.map +1 -1
  20. package/dist/server/types.d.ts +64 -2
  21. package/dist/server/types.d.ts.map +1 -1
  22. package/dist/server.cjs +423 -110
  23. package/dist/server.cjs.map +1 -1
  24. package/dist/server.js +423 -110
  25. package/dist/server.js.map +1 -1
  26. package/dist/style.css +30 -18
  27. package/dist/vue/View.vue.d.ts.map +1 -1
  28. package/dist/vue/composables/useDeckEditor.d.ts.map +1 -1
  29. package/dist/vue/index.d.ts +1 -1
  30. package/dist/vue/index.d.ts.map +1 -1
  31. package/dist/vue/subscription.d.ts +16 -0
  32. package/dist/vue/subscription.d.ts.map +1 -0
  33. package/dist/vue/transport.d.ts +16 -5
  34. package/dist/vue/transport.d.ts.map +1 -1
  35. package/dist/vue.cjs +110 -21
  36. package/dist/vue.cjs.map +1 -1
  37. package/dist/vue.js +110 -21
  38. package/dist/vue.js.map +1 -1
  39. package/package.json +11 -11
  40. package/dist/contract-BhN3yKJC.cjs +0 -36
  41. package/dist/contract-BhN3yKJC.cjs.map +0 -1
  42. package/dist/contract-CIt1ZAtt.js +0 -19
  43. package/dist/contract-CIt1ZAtt.js.map +0 -1
  44. package/dist/plugin-BOq5YkTl.cjs.map +0 -1
  45. package/dist/plugin-CAhxJ5WM.js.map +0 -1
package/dist/vue.js CHANGED
@@ -1,5 +1,5 @@
1
- import { a as pluginCore, d as errorMessage, f as TOOL_DEFINITION, p as TOOL_NAME } from "./plugin-CAhxJ5WM.js";
2
- import { n as SCRIPT_CHANGED_EVENT, r as shouldReloadForScriptChange, t as GENERATION_EVENT } from "./contract-CIt1ZAtt.js";
1
+ import { a as pluginCore, h as TOOL_NAME, m as TOOL_DEFINITION, p as errorMessage } from "./plugin-Jo8iGv4K.js";
2
+ import { a as shouldReloadForScriptChange, i as sameRoot, n as SCRIPT_CHANGED_EVENT, t as GENERATION_EVENT } from "./contract-BnIl6w_f.js";
3
3
  import { mulmoBeatSchema, mulmoScriptSchema } from "@mulmocast/types";
4
4
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineAsyncComponent, defineComponent, inject, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, openBlock, reactive, ref, renderList, toDisplayString, unref, vModelText, vShow, watch, withDirectives, withModifiers } from "vue";
5
5
  import { beatsOf, withBeats } from "@mulmocast/beat-editor";
@@ -215,6 +215,57 @@ function focusLeftContainer(container, movedTo) {
215
215
  return !container.contains(movedTo);
216
216
  }
217
217
  //#endregion
218
+ //#region src/vue/subscription.ts
219
+ /** A caller that predates roots is asking for the host's default root. */
220
+ var DEFAULT_ROOT_GETTER = () => void 0;
221
+ /**
222
+ * The object form is checked at runtime, not only by the type.
223
+ *
224
+ * This package is published, so a JavaScript consumer reaches these functions
225
+ * with no call-site checking at all. An object missing `root` type-checks
226
+ * nowhere and passed through here unchanged, and the failure surfaced much
227
+ * later as `sub.root is not a function` — thrown inside a pubsub delivery,
228
+ * where there is no caller left to catch it and the only symptom is a View
229
+ * that silently stops updating (CodeRabbit on #3015).
230
+ *
231
+ * A missing `root` is the one field with a safe answer: absent means the
232
+ * default root, which is exactly what a caller who did not think about roots
233
+ * intended. A missing `filePath` or `handler` has no such answer, so it
234
+ * throws HERE, at the subscribe call, where the stack points at the bug.
235
+ */
236
+ function checkedSubscription(subscription, label) {
237
+ if (typeof subscription.filePath !== "function" || typeof subscription.handler !== "function") throw new TypeError(`${label}: filePath and handler must both be functions`);
238
+ if (subscription.root === void 0) return {
239
+ ...subscription,
240
+ root: DEFAULT_ROOT_GETTER
241
+ };
242
+ if (typeof subscription.root !== "function") throw new TypeError(`${label}: root must be a function returning the root id, or be omitted`);
243
+ return subscription;
244
+ }
245
+ function normalizeGenerationSubscription(first, legacyHandler) {
246
+ if (typeof first !== "function") return checkedSubscription(first, "onGenerationEvent(subscription)");
247
+ if (!legacyHandler) throw new TypeError("onGenerationEvent(filePath, handler): handler is required");
248
+ return {
249
+ filePath: first,
250
+ root: DEFAULT_ROOT_GETTER,
251
+ handler: legacyHandler
252
+ };
253
+ }
254
+ function normalizeScriptChangedSubscription(first, legacyOwnOrigin, legacyHandler) {
255
+ if (typeof first !== "function") {
256
+ const checked = checkedSubscription(first, "onScriptChanged(subscription)");
257
+ if (typeof checked.ownOrigin !== "string") throw new TypeError("onScriptChanged(subscription): ownOrigin must be a string");
258
+ return checked;
259
+ }
260
+ if (typeof legacyOwnOrigin !== "string" || !legacyHandler) throw new TypeError("onScriptChanged(filePath, ownOrigin, handler): ownOrigin and handler are required");
261
+ return {
262
+ filePath: first,
263
+ root: DEFAULT_ROOT_GETTER,
264
+ ownOrigin: legacyOwnOrigin,
265
+ handler: legacyHandler
266
+ };
267
+ }
268
+ //#endregion
218
269
  //#region src/vue/transport.ts
219
270
  var GENERATION_EVENT_KINDS = /* @__PURE__ */ new Set([
220
271
  "beatImage",
@@ -223,26 +274,53 @@ var GENERATION_EVENT_KINDS = /* @__PURE__ */ new Set([
223
274
  "movie",
224
275
  "pdf"
225
276
  ]);
277
+ /**
278
+ * A field that is absent, or a string.
279
+ *
280
+ * `undefined` is a legitimate answer for both `root` and `origin`, so a
281
+ * present-but-wrong-typed value CANNOT be flattened into it: `root: 42` read
282
+ * as "no root" makes a named root's event look like a default-root one, and
283
+ * the subscriber then routes another repository's script to this View
284
+ * (CodeRabbit on #3015 — the same shape the dispatch boundary was just fixed
285
+ * for). Malformed means malformed; the caller rejects the payload.
286
+ */
287
+ function optionalString(value) {
288
+ if (value === void 0) return {
289
+ ok: true,
290
+ value: void 0
291
+ };
292
+ return typeof value === "string" ? {
293
+ ok: true,
294
+ value
295
+ } : { ok: false };
296
+ }
226
297
  function parseScriptChangedEvent(payload) {
227
298
  if (!isRecord(payload)) return null;
228
- const { filePath, origin } = payload;
299
+ const { filePath, origin, root } = payload;
229
300
  if (typeof filePath !== "string") return null;
301
+ const parsedOrigin = optionalString(origin);
302
+ const parsedRoot = optionalString(root);
303
+ if (!parsedOrigin.ok || !parsedRoot.ok) return null;
230
304
  return {
231
305
  filePath,
232
- ...typeof origin === "string" ? { origin } : {}
306
+ ...parsedOrigin.value !== void 0 ? { origin: parsedOrigin.value } : {},
307
+ ...parsedRoot.value !== void 0 ? { root: parsedRoot.value } : {}
233
308
  };
234
309
  }
235
310
  function parseGenerationEvent(payload) {
236
311
  if (!isRecord(payload)) return null;
237
- const { kind, filePath, key, done, error } = payload;
312
+ const { kind, filePath, key, done, error, root } = payload;
238
313
  if (typeof kind !== "string" || !GENERATION_EVENT_KINDS.has(kind)) return null;
239
314
  if (typeof filePath !== "string" || typeof key !== "string" || typeof done !== "boolean") return null;
315
+ const parsedRoot = optionalString(root);
316
+ if (!parsedRoot.ok) return null;
240
317
  return {
241
318
  kind,
242
319
  filePath,
243
320
  key,
244
321
  done,
245
- ...typeof error === "string" ? { error } : {}
322
+ ...typeof error === "string" ? { error } : {},
323
+ ...parsedRoot.value !== void 0 ? { root: parsedRoot.value } : {}
246
324
  };
247
325
  }
248
326
  function useMulmoScriptTransport() {
@@ -269,12 +347,13 @@ function useMulmoScriptTransport() {
269
347
  data: result
270
348
  };
271
349
  }
272
- function onGenerationEvent(filePath, handler) {
350
+ function onGenerationEvent(first, legacyHandler) {
351
+ const { filePath, root, handler } = normalizeGenerationSubscription(first, legacyHandler);
273
352
  return runtime.pubsub.subscribe(GENERATION_EVENT, (payload) => {
274
353
  const event = parseGenerationEvent(payload);
275
354
  if (!event) return;
276
355
  const current = filePath();
277
- if (!current || event.filePath !== current) return;
356
+ if (!current || event.filePath !== current || !sameRoot(event.root, root())) return;
278
357
  handler(event);
279
358
  });
280
359
  }
@@ -285,11 +364,12 @@ function useMulmoScriptTransport() {
285
364
  * on them would rebuild the element the caret is in on every keystroke, so they are dropped
286
365
  * here. A write from the agent carries no origin and always reaches the handler.
287
366
  */
288
- function onScriptChanged(filePath, ownOrigin, handler) {
367
+ function onScriptChanged(first, legacyOwnOrigin, legacyHandler) {
368
+ const { filePath, root, ownOrigin, handler } = normalizeScriptChangedSubscription(first, legacyOwnOrigin, legacyHandler);
289
369
  return runtime.pubsub.subscribe(SCRIPT_CHANGED_EVENT, (payload) => {
290
370
  const event = parseScriptChangedEvent(payload);
291
371
  if (!event) return;
292
- if (!shouldReloadForScriptChange(event, filePath(), ownOrigin)) return;
372
+ if (!shouldReloadForScriptChange(event, filePath(), ownOrigin, root())) return;
293
373
  handler();
294
374
  });
295
375
  }
@@ -646,9 +726,14 @@ function useDeckEditor({ api, filePath, effectiveScript, commitScript }) {
646
726
  * flushing cannot clobber it out of order.
647
727
  */
648
728
  function watchForeignWrites(reload) {
649
- return api.onScriptChanged(() => filePath.value, EDITOR_ORIGIN, () => {
650
- flushPendingDeckSave();
651
- reload();
729
+ return api.onScriptChanged({
730
+ filePath: () => filePath.value,
731
+ root: () => void 0,
732
+ ownOrigin: EDITOR_ORIGIN,
733
+ handler: () => {
734
+ flushPendingDeckSave();
735
+ reload();
736
+ }
652
737
  });
653
738
  }
654
739
  return {
@@ -2010,14 +2095,18 @@ var View_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompo
2010
2095
  }
2011
2096
  onMounted(initializeScript);
2012
2097
  watch(() => props.selectedResult, initializeScript);
2013
- const unsubscribeGenerationEvents = api.onGenerationEvent(() => filePath.value, (event) => {
2014
- if (!event.done) {
2015
- reflectGenerationStart(event);
2016
- return;
2098
+ const unsubscribeGenerationEvents = api.onGenerationEvent({
2099
+ filePath: () => filePath.value,
2100
+ root: () => void 0,
2101
+ handler: (event) => {
2102
+ if (!event.done) {
2103
+ reflectGenerationStart(event);
2104
+ return;
2105
+ }
2106
+ reflectGenerationFinish(event).catch((err) => {
2107
+ console.error("[presentMulmoScript] reload on finish failed:", err);
2108
+ });
2017
2109
  }
2018
- reflectGenerationFinish(event).catch((err) => {
2019
- console.error("[presentMulmoScript] reload on finish failed:", err);
2020
- });
2021
2110
  });
2022
2111
  function reflectGenerationStart(entry) {
2023
2112
  if (entry.kind === "beatImage") {
@@ -2353,7 +2442,7 @@ var _plugin_vue_export_helper_default = (sfc, props) => {
2353
2442
  };
2354
2443
  //#endregion
2355
2444
  //#region src/vue/View.vue
2356
- var View_default = /*#__PURE__*/ _plugin_vue_export_helper_default(View_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-f9957eaf"]]);
2445
+ var View_default = /*#__PURE__*/ _plugin_vue_export_helper_default(View_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-2d5f76ac"]]);
2357
2446
  //#endregion
2358
2447
  //#region src/vue/Preview.vue?vue&type=script&setup=true&lang.ts
2359
2448
  var _hoisted_1 = {