@mulmoclaude/collection-plugin 0.5.3 → 0.5.6

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.
package/dist/server.js CHANGED
@@ -7,6 +7,7 @@ import { randomBytes, randomUUID } from "node:crypto";
7
7
  import { z } from "zod";
8
8
  //#region src/server/host.ts
9
9
  var current = null;
10
+ var changePublisher = null;
10
11
  /** Wire the engine to a host. Call once at server startup, before any
11
12
  * collection storage operation. Re-binding to a *different* host throws —
12
13
  * silently redirecting later filesystem operations to another workspace
@@ -15,6 +16,22 @@ function configureCollectionHost(host) {
15
16
  if (current !== null && current !== host) throw new Error("@mulmoclaude/collection-plugin/server: configureCollectionHost() was already called with a different host");
16
17
  current = host;
17
18
  }
19
+ /** Wire a publisher that broadcasts record-change events; the host bridges it
20
+ * to its pubsub. Kept SEPARATE from `configureCollectionHost` because the
21
+ * host's pubsub instance isn't ready at host-binding time (the binding is set
22
+ * at the top of server startup, the pubsub later). Optional: left unset, every
23
+ * write is silent — the default for tests and for a host that doesn't want
24
+ * live view updates. Pass `null` to detach (test teardown). */
25
+ function setCollectionChangePublisher(publish) {
26
+ changePublisher = publish;
27
+ }
28
+ /** Broadcast a record-change event if a publisher is wired (no-op otherwise).
29
+ * Called from the write path (`writeItem`/`deleteItem`). The wired publisher is
30
+ * expected to be fire-and-forget (it wraps its own pubsub call in try/catch),
31
+ * so this stays a thin pass-through and never throws into the write. */
32
+ function publishCollectionChange(payload) {
33
+ changePublisher?.(payload);
34
+ }
18
35
  function requireHost() {
19
36
  if (current === null) throw new Error("@mulmoclaude/collection-plugin/server: configureCollectionHost() was not called by the host");
20
37
  return current;
@@ -391,13 +408,12 @@ async function writeItem(dataDir, itemId, item, opts = {}) {
391
408
  } finally {
392
409
  await handle.close();
393
410
  }
394
- return {
395
- kind: "ok",
396
- itemId: safeId,
397
- item
398
- };
399
- }
400
- await writeFileAtomic(filePath, payload);
411
+ } else await writeFileAtomic(filePath, payload);
412
+ if (opts.slug) publishCollectionChange({
413
+ slug: opts.slug,
414
+ ids: [safeId],
415
+ op: "upsert"
416
+ });
401
417
  return {
402
418
  kind: "ok",
403
419
  itemId: safeId,
@@ -423,6 +439,11 @@ async function deleteItem(dataDir, itemId, opts = {}) {
423
439
  const filePath = itemFilePath(dataDir, safeId);
424
440
  try {
425
441
  await unlink(filePath);
442
+ if (opts.slug) publishCollectionChange({
443
+ slug: opts.slug,
444
+ ids: [safeId],
445
+ op: "delete"
446
+ });
426
447
  return {
427
448
  kind: "ok",
428
449
  itemId: safeId
@@ -1434,7 +1455,8 @@ async function maybeSpawnSuccessor(slug, schema, dataDir, sourceItem, sourceId,
1434
1455
  try {
1435
1456
  const result = await writeItem(dataDir, computed.id, computed.record, {
1436
1457
  ...ioOpts,
1437
- refuseOverwrite: true
1458
+ refuseOverwrite: true,
1459
+ slug
1438
1460
  });
1439
1461
  if (result.kind === "ok") log.info("collections", "spawned successor", {
1440
1462
  slug,
@@ -1682,6 +1704,6 @@ async function deleteCustomView(collection, viewId, opts = {}) {
1682
1704
  };
1683
1705
  }
1684
1706
  //#endregion
1685
- export { COMPUTED_TYPES, CollectionSchemaZ, SCHEMA_FILE, acceptParsedSchema, advanceTriggerDate, buildActionSeedPrompt, buildCollectionActionSeedPrompt, computeSuccessor, configureCollectionHost, daysInMonth, deleteCollection, deleteCollectionRefusalMessage, deleteCustomView, deleteItem, discoverCollections, enrichItems, formatCivil, generateItemId, getWorkspaceRoot, isContainedInRoot, isContainedInWorkspace, isSafeActionTemplatePath, isSafeCustomViewPath, isSafeTemplatePath, isTriggerDue, itemFilePath, listItems, loadCollection, log, maybeSpawnSuccessor, parseCivil, readCustomViewHtml, readItem, readSkillTemplate, resolveCreateItemId, resolveDataDir, resolveEvery, resolveTemplatePath, safeRecordId, safeSlugName, successorId, toDetail, toSummary, validateCollectionRecords, validateRecordObject, writeItem };
1707
+ export { COMPUTED_TYPES, CollectionSchemaZ, SCHEMA_FILE, acceptParsedSchema, advanceTriggerDate, buildActionSeedPrompt, buildCollectionActionSeedPrompt, computeSuccessor, configureCollectionHost, daysInMonth, deleteCollection, deleteCollectionRefusalMessage, deleteCustomView, deleteItem, discoverCollections, enrichItems, formatCivil, generateItemId, getWorkspaceRoot, isContainedInRoot, isContainedInWorkspace, isSafeActionTemplatePath, isSafeCustomViewPath, isSafeTemplatePath, isTriggerDue, itemFilePath, listItems, loadCollection, log, maybeSpawnSuccessor, parseCivil, publishCollectionChange, readCustomViewHtml, readItem, readSkillTemplate, resolveCreateItemId, resolveDataDir, resolveEvery, resolveTemplatePath, safeRecordId, safeSlugName, setCollectionChangePublisher, successorId, toDetail, toSummary, validateCollectionRecords, validateRecordObject, writeItem };
1686
1708
 
1687
1709
  //# sourceMappingURL=server.js.map