dsh-draw 0.2.14 → 0.2.15

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 (40) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README-es.md +16 -4
  3. package/README-hi.md +16 -4
  4. package/README-pt.md +16 -4
  5. package/README-zh.md +16 -4
  6. package/README.md +16 -5
  7. package/lib/client.js +69 -65
  8. package/lib/client.js.map +1 -1
  9. package/lib/index.js +49 -7
  10. package/lib/typert.host.js +1 -1
  11. package/lib/types/client/index.d.ts +12 -0
  12. package/lib/types/client/index.d.ts.map +1 -1
  13. package/lib/types/client/index.js +23 -5
  14. package/lib/types/client/remote.d.ts +110 -31
  15. package/lib/types/client/remote.d.ts.map +1 -1
  16. package/lib/types/client/styles.d.ts.map +1 -1
  17. package/lib/types/client/styles.js +24 -7
  18. package/lib/types/event-gate.d.ts +24 -2
  19. package/lib/types/event-gate.d.ts.map +1 -1
  20. package/lib/types/event-gate.js +31 -3
  21. package/lib/types/index.d.ts.map +1 -1
  22. package/lib/types/index.js +19 -2
  23. package/lib/types/session-events.d.ts.map +1 -1
  24. package/lib/types/session-events.js +9 -2
  25. package/lib/types/typert.host.d.ts +110 -31
  26. package/lib/types/typert.host.d.ts.map +1 -1
  27. package/lib/types/version.d.ts +1 -1
  28. package/lib/types/version.js +1 -1
  29. package/lib/types/wire.d.ts +220 -62
  30. package/lib/types/wire.d.ts.map +1 -1
  31. package/lib/types/wire.js +21 -35
  32. package/lib/{wire-DLW8WmDW.js → wire-BvocRNv3.js} +26 -55
  33. package/package.json +16 -14
  34. package/src/client/index.ts +20 -5
  35. package/src/client/styles.ts +24 -6
  36. package/src/event-gate.ts +45 -3
  37. package/src/index.ts +16 -2
  38. package/src/session-events.ts +9 -2
  39. package/src/version.ts +1 -1
  40. package/src/wire.ts +22 -35
package/lib/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { i as statusToView, n as imageToWire, r as probeToWire, t as DRAW_INVOCATIONS } from "./wire-DLW8WmDW.js";
1
+ import { i as statusToView, n as imageToWire, r as probeToWire, t as DRAW_INVOCATIONS } from "./wire-BvocRNv3.js";
2
2
  import { credentialRef } from "@deepseek-ai/dsh-credentials";
3
3
  import z from "@deepseek-ai/schemastery";
4
4
  import { Context } from "@deepseek-ai/cordis";
@@ -638,9 +638,41 @@ function probeIgnorableAppend() {
638
638
  return false;
639
639
  }
640
640
  }
641
- /** The gate over the host's known types plus the probed envelope support. */
642
- function makeHostEventGate() {
643
- return makeEventGate(KNOWN_SESSION_EVENT_TYPES, probeIgnorableAppend());
641
+ /**
642
+ * The gate over the host's known types plus the probed envelope support.
643
+ *
644
+ * A refusal used to be completely silent: the accounting moved to the
645
+ * in-memory fallback ledger and nothing said so. The first refusal now warns
646
+ * once through `warn` (the mount-time probe result is also readable on the
647
+ * returned function), so a degraded session is visible without spamming the
648
+ * log on every commit.
649
+ *
650
+ * @param warn - sink for the one-time degradation warning.
651
+ * @returns the gate carrying its probe result.
652
+ */
653
+ function makeHostEventGate(warn = () => {}) {
654
+ const ignorableAppend = probeIgnorableAppend();
655
+ const gate = makeEventGate(KNOWN_SESSION_EVENT_TYPES, ignorableAppend);
656
+ let warned = false;
657
+ const hostGate = ((type) => {
658
+ const decision = gate(type);
659
+ if (!decision.append && !warned) {
660
+ warned = true;
661
+ warn("dsh-draw: this host neither knows the draw/generated event type nor honors the ignorable envelope, so the audit event is not written; the in-memory fallback ledger keeps quota exact for this session and resets when the session restarts");
662
+ }
663
+ return decision;
664
+ });
665
+ Object.defineProperties(hostGate, {
666
+ ignorableAppend: {
667
+ value: ignorableAppend,
668
+ enumerable: true
669
+ },
670
+ knownTypes: {
671
+ value: KNOWN_SESSION_EVENT_TYPES,
672
+ enumerable: true
673
+ }
674
+ });
675
+ return hostGate;
644
676
  }
645
677
  //#endregion
646
678
  //#region src/http.ts
@@ -1359,7 +1391,7 @@ var EngineRouter = class {
1359
1391
  * @module dsh-draw/version
1360
1392
  */
1361
1393
  /** Plugin version; must equal the `version` field in `package.json`. */
1362
- const PLUGIN_VERSION = "0.2.14";
1394
+ const PLUGIN_VERSION = "0.2.15";
1363
1395
  //#endregion
1364
1396
  //#region src/service.ts
1365
1397
  /**
@@ -1709,16 +1741,26 @@ async function apply(ctx, config) {
1709
1741
  attachments: () => ctx.get("attachments"),
1710
1742
  sessions: () => ctx.get("sessions")
1711
1743
  }, {
1712
- gate: makeHostEventGate(),
1744
+ gate: makeHostEventGate((message) => logger.warn(message)),
1713
1745
  warn: (message) => logger.warn(message)
1714
1746
  });
1715
1747
  ctx.effect(() => ctx.tools.register(imageGenerateTool(drawer, resolved)), "dsh-draw: image_generate tool");
1716
- await ctx.plugin(DrawService, {
1748
+ const serviceFiber = ctx.plugin(DrawService, {
1717
1749
  config: resolved,
1718
1750
  router,
1719
1751
  drawer,
1720
1752
  credentials: credentials()
1721
1753
  });
1754
+ ctx.effect(() => () => {
1755
+ serviceFiber.dispose();
1756
+ }, "dsh-draw: draw service");
1757
+ try {
1758
+ await serviceFiber;
1759
+ } catch (error) {
1760
+ if (ctx.fiber.uid === null) return;
1761
+ throw error;
1762
+ }
1763
+ if (ctx.fiber.uid === null) return;
1722
1764
  logger.info(`image generation enabled: ${resolved.engines.map((engine) => engine.id).join(", ")} (preferred ${resolved.defaultEngine})`);
1723
1765
  }
1724
1766
  //#endregion
@@ -1,4 +1,4 @@
1
- import { t as DRAW_INVOCATIONS } from "./wire-DLW8WmDW.js";
1
+ import { t as DRAW_INVOCATIONS } from "./wire-BvocRNv3.js";
2
2
  //#region src/typert.host.ts
3
3
  /**
4
4
  * The hand-written Typert HOST manifest for `dsh-draw`, exported as `./typert`
@@ -32,4 +32,16 @@ export declare const inject: string[];
32
32
  * @param ctx - client root context.
33
33
  */
34
34
  export declare function apply(ctx: ClientContext): Promise<void>;
35
+ /**
36
+ * Read the current session id from the sessions store face (structural: the
37
+ * store shape differs across harness lines, so only the leaves are read).
38
+ *
39
+ * On the 0.1.6 line `SessionListState.current` no longer exists, so the card's
40
+ * regenerate belongs to the session the main view retains: pick the listed
41
+ * session whose `retainedBy.mainView` is set — the same rule the upstream
42
+ * session store applies when it resolves its main binding. Without a retained
43
+ * session the guard returns undefined and the caller reports it instead of
44
+ * regenerating against an unknown session.
45
+ */
46
+ export declare function currentSessionId(sessions: unknown): string | undefined;
35
47
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAWnE,OAAO,EAAU,KAAK,aAAa,EAAE,MAAM,cAAc,CAAA;AAMzD,YAAY,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AACvF,YAAY,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAC1F,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAE9I,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,kBAAkB;QAC1B,4CAA4C;QAC5C,MAAM,EAAE,aAAa,CAAA;KACtB;CACF;AAED,iDAAiD;AACjD,eAAO,MAAM,EAAE,SAAS,CAAA;AAExB,kFAAkF;AAClF,eAAO,MAAM,IAAI,aAAa,CAAA;AAE9B,2FAA2F;AAC3F,eAAO,MAAM,MAAM,UAA4C,CAAA;AAc/D;;;;;GAKG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAsD7D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAWnE,OAAO,EAAU,KAAK,aAAa,EAAE,MAAM,cAAc,CAAA;AAMzD,YAAY,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AACvF,YAAY,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAC1F,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAE9I,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,kBAAkB;QAC1B,4CAA4C;QAC5C,MAAM,EAAE,aAAa,CAAA;KACtB;CACF;AAED,iDAAiD;AACjD,eAAO,MAAM,EAAE,SAAS,CAAA;AAExB,kFAAkF;AAClF,eAAO,MAAM,IAAI,aAAa,CAAA;AAE9B,2FAA2F;AAC3F,eAAO,MAAM,MAAM,UAA4C,CAAA;AAc/D;;;;;GAKG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAsD7D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAmBtE"}
@@ -79,10 +79,17 @@ export async function apply(ctx) {
79
79
  });
80
80
  }
81
81
  /**
82
- * Read the current session id from the sessions store face (structural:
83
- * the store shape differs across harness lines, so only the leaf is read).
82
+ * Read the current session id from the sessions store face (structural: the
83
+ * store shape differs across harness lines, so only the leaves are read).
84
+ *
85
+ * On the 0.1.6 line `SessionListState.current` no longer exists, so the card's
86
+ * regenerate belongs to the session the main view retains: pick the listed
87
+ * session whose `retainedBy.mainView` is set — the same rule the upstream
88
+ * session store applies when it resolves its main binding. Without a retained
89
+ * session the guard returns undefined and the caller reports it instead of
90
+ * regenerating against an unknown session.
84
91
  */
85
- function currentSessionId(sessions) {
92
+ export function currentSessionId(sessions) {
86
93
  try {
87
94
  const list = sessions?.list;
88
95
  if (typeof list !== 'object' || list === null)
@@ -90,8 +97,19 @@ function currentSessionId(sessions) {
90
97
  const getSnapshot = list.getSnapshot;
91
98
  if (typeof getSnapshot !== 'function')
92
99
  return undefined;
93
- const current = getSnapshot().current;
94
- return typeof current === 'string' ? current : undefined;
100
+ const byId = getSnapshot().byId;
101
+ if (typeof byId !== 'object' || byId === null)
102
+ return undefined;
103
+ for (const candidate of Object.values(byId)) {
104
+ if (typeof candidate !== 'object' || candidate === null)
105
+ continue;
106
+ const retained = candidate.retainedBy;
107
+ const mainView = typeof retained?.mainView === 'number' ? retained.mainView : 0;
108
+ const id = candidate.id;
109
+ if (mainView > 0 && typeof id === 'string')
110
+ return id;
111
+ }
112
+ return undefined;
95
113
  }
96
114
  catch {
97
115
  return undefined;
@@ -46,8 +46,8 @@ export declare const DRAW_REMOTE: Readonly<{
46
46
  }>;
47
47
  readonly parameters: readonly never[];
48
48
  readonly result: Readonly<{
49
- mode: "strict";
50
- typeSymbol: "dsh-draw/types#DrawStatusSnapshot";
49
+ mode: 'strict';
50
+ typeSymbol: string;
51
51
  schema: import("zod").ZodObject<{
52
52
  pluginVersion: import("zod").ZodString;
53
53
  engines: import("zod").ZodArray<import("zod").ZodObject<{
@@ -76,6 +76,34 @@ export declare const DRAW_REMOTE: Readonly<{
76
76
  requestTimeoutMs: import("zod").ZodNumber;
77
77
  maxImagesPerCall: import("zod").ZodNumber;
78
78
  }, import("zod/v4/core").$strip>;
79
+ create: () => import("zod").ZodObject<{
80
+ pluginVersion: import("zod").ZodString;
81
+ engines: import("zod").ZodArray<import("zod").ZodObject<{
82
+ id: import("zod").ZodString;
83
+ model: import("zod").ZodString;
84
+ baseUrl: import("zod").ZodString;
85
+ apiKeyRef: import("zod").ZodString;
86
+ enabled: import("zod").ZodBoolean;
87
+ preferred: import("zod").ZodBoolean;
88
+ credential: import("zod").ZodObject<{
89
+ configured: import("zod").ZodBoolean;
90
+ source: import("zod").ZodOptional<import("zod").ZodString>;
91
+ writable: import("zod").ZodBoolean;
92
+ }, import("zod/v4/core").$strip>;
93
+ health: import("zod").ZodObject<{
94
+ consecutiveFailures: import("zod").ZodNumber;
95
+ cooldownUntil: import("zod").ZodNullable<import("zod").ZodNumber>;
96
+ lastError: import("zod").ZodNullable<import("zod").ZodString>;
97
+ lastStatus: import("zod").ZodNullable<import("zod").ZodNumber>;
98
+ }, import("zod/v4/core").$strip>;
99
+ }, import("zod/v4/core").$strip>>;
100
+ quota: import("zod").ZodObject<{
101
+ maxGenerationsPerSession: import("zod").ZodNumber;
102
+ maxBytesPerSession: import("zod").ZodNumber;
103
+ }, import("zod/v4/core").$strip>;
104
+ requestTimeoutMs: import("zod").ZodNumber;
105
+ maxImagesPerCall: import("zod").ZodNumber;
106
+ }, import("zod/v4/core").$strip>;
79
107
  }>;
80
108
  readonly sourceLocation: Readonly<{
81
109
  file: "src/wire.ts";
@@ -95,14 +123,15 @@ export declare const DRAW_REMOTE: Readonly<{
95
123
  wire: string;
96
124
  source: "json";
97
125
  codec: Readonly<{
98
- mode: "strict";
99
- typeSymbol: "dsh-draw/types#EngineId";
126
+ mode: 'strict';
127
+ typeSymbol: string;
100
128
  schema: import("zod").ZodString;
129
+ create: () => import("zod").ZodString;
101
130
  }>;
102
131
  }>[];
103
132
  readonly result: Readonly<{
104
- mode: "strict";
105
- typeSymbol: "dsh-draw/types#DrawProbeResult";
133
+ mode: 'strict';
134
+ typeSymbol: string;
106
135
  schema: import("zod").ZodObject<{
107
136
  engineId: import("zod").ZodString;
108
137
  reachable: import("zod").ZodBoolean;
@@ -111,6 +140,14 @@ export declare const DRAW_REMOTE: Readonly<{
111
140
  note: import("zod").ZodString;
112
141
  credentialConfigured: import("zod").ZodBoolean;
113
142
  }, import("zod/v4/core").$strip>;
143
+ create: () => import("zod").ZodObject<{
144
+ engineId: import("zod").ZodString;
145
+ reachable: import("zod").ZodBoolean;
146
+ httpStatus: import("zod").ZodNullable<import("zod").ZodNumber>;
147
+ target: import("zod").ZodString;
148
+ note: import("zod").ZodString;
149
+ credentialConfigured: import("zod").ZodBoolean;
150
+ }, import("zod/v4/core").$strip>;
114
151
  }>;
115
152
  readonly sourceLocation: Readonly<{
116
153
  file: "src/wire.ts";
@@ -125,33 +162,30 @@ export declare const DRAW_REMOTE: Readonly<{
125
162
  readonly invocation: Readonly<{
126
163
  kind: "direct";
127
164
  }>;
128
- readonly parameters: readonly (Readonly<{
129
- name: string;
130
- wire: string;
131
- source: "json";
132
- codec: Readonly<{
133
- mode: "strict";
134
- typeSymbol: "dsh-draw/types#EngineId";
135
- schema: import("zod").ZodString;
136
- }>;
137
- }> | Readonly<{
165
+ readonly parameters: readonly Readonly<{
138
166
  name: string;
139
167
  wire: string;
140
168
  source: "json";
141
169
  codec: Readonly<{
142
- mode: "strict";
143
- typeSymbol: "dsh-draw/types#CredentialValue";
170
+ mode: 'strict';
171
+ typeSymbol: string;
144
172
  schema: import("zod").ZodString;
173
+ create: () => import("zod").ZodString;
145
174
  }>;
146
- }>)[];
175
+ }>[];
147
176
  readonly result: Readonly<{
148
- mode: "strict";
149
- typeSymbol: "dsh-draw/types#CredentialActionResult";
177
+ mode: 'strict';
178
+ typeSymbol: string;
150
179
  schema: import("zod").ZodObject<{
151
180
  engineId: import("zod").ZodString;
152
181
  reference: import("zod").ZodString;
153
182
  note: import("zod").ZodString;
154
183
  }, import("zod/v4/core").$strip>;
184
+ create: () => import("zod").ZodObject<{
185
+ engineId: import("zod").ZodString;
186
+ reference: import("zod").ZodString;
187
+ note: import("zod").ZodString;
188
+ }, import("zod/v4/core").$strip>;
155
189
  }>;
156
190
  readonly sourceLocation: Readonly<{
157
191
  file: "src/wire.ts";
@@ -171,19 +205,25 @@ export declare const DRAW_REMOTE: Readonly<{
171
205
  wire: string;
172
206
  source: "json";
173
207
  codec: Readonly<{
174
- mode: "strict";
175
- typeSymbol: "dsh-draw/types#EngineId";
208
+ mode: 'strict';
209
+ typeSymbol: string;
176
210
  schema: import("zod").ZodString;
211
+ create: () => import("zod").ZodString;
177
212
  }>;
178
213
  }>[];
179
214
  readonly result: Readonly<{
180
- mode: "strict";
181
- typeSymbol: "dsh-draw/types#CredentialActionResult";
215
+ mode: 'strict';
216
+ typeSymbol: string;
182
217
  schema: import("zod").ZodObject<{
183
218
  engineId: import("zod").ZodString;
184
219
  reference: import("zod").ZodString;
185
220
  note: import("zod").ZodString;
186
221
  }, import("zod/v4/core").$strip>;
222
+ create: () => import("zod").ZodObject<{
223
+ engineId: import("zod").ZodString;
224
+ reference: import("zod").ZodString;
225
+ note: import("zod").ZodString;
226
+ }, import("zod/v4/core").$strip>;
187
227
  }>;
188
228
  readonly sourceLocation: Readonly<{
189
229
  file: "src/wire.ts";
@@ -203,17 +243,18 @@ export declare const DRAW_REMOTE: Readonly<{
203
243
  wire: string;
204
244
  source: "json";
205
245
  codec: Readonly<{
206
- mode: "strict";
207
- typeSymbol: "dsh-draw/types#SessionId";
246
+ mode: 'strict';
247
+ typeSymbol: string;
208
248
  schema: import("zod").ZodString;
249
+ create: () => import("zod").ZodString;
209
250
  }>;
210
251
  }> | Readonly<{
211
252
  name: string;
212
253
  wire: string;
213
254
  source: "json";
214
255
  codec: Readonly<{
215
- mode: "strict";
216
- typeSymbol: "dsh-draw/types#RegenerateArgs";
256
+ mode: 'strict';
257
+ typeSymbol: string;
217
258
  schema: import("zod").ZodObject<{
218
259
  prompt: import("zod").ZodString;
219
260
  size: import("zod").ZodOptional<import("zod").ZodString>;
@@ -222,11 +263,19 @@ export declare const DRAW_REMOTE: Readonly<{
222
263
  style: import("zod").ZodOptional<import("zod").ZodString>;
223
264
  engine: import("zod").ZodOptional<import("zod").ZodString>;
224
265
  }, import("zod/v4/core").$loose>;
266
+ create: () => import("zod").ZodObject<{
267
+ prompt: import("zod").ZodString;
268
+ size: import("zod").ZodOptional<import("zod").ZodString>;
269
+ count: import("zod").ZodOptional<import("zod").ZodNumber>;
270
+ quality: import("zod").ZodOptional<import("zod").ZodString>;
271
+ style: import("zod").ZodOptional<import("zod").ZodString>;
272
+ engine: import("zod").ZodOptional<import("zod").ZodString>;
273
+ }, import("zod/v4/core").$loose>;
225
274
  }>;
226
275
  }>)[];
227
276
  readonly result: Readonly<{
228
- mode: "strict";
229
- typeSymbol: "dsh-draw/types#DrawRegenerateResult";
277
+ mode: 'strict';
278
+ typeSymbol: string;
230
279
  schema: import("zod").ZodObject<{
231
280
  engine: import("zod").ZodString;
232
281
  model: import("zod").ZodString;
@@ -257,6 +306,36 @@ export declare const DRAW_REMOTE: Readonly<{
257
306
  status: import("zod").ZodOptional<import("zod").ZodNumber>;
258
307
  }, import("zod/v4/core").$strip>>;
259
308
  }, import("zod/v4/core").$strip>;
309
+ create: () => import("zod").ZodObject<{
310
+ engine: import("zod").ZodString;
311
+ model: import("zod").ZodString;
312
+ size: import("zod").ZodString;
313
+ images: import("zod").ZodArray<import("zod").ZodObject<{
314
+ attachmentId: import("zod").ZodString;
315
+ mediaType: import("zod").ZodString;
316
+ bytes: import("zod").ZodNumber;
317
+ width: import("zod").ZodNumber;
318
+ height: import("zod").ZodNumber;
319
+ name: import("zod").ZodOptional<import("zod").ZodString>;
320
+ }, import("zod/v4/core").$strip>>;
321
+ quota: import("zod").ZodObject<{
322
+ generations: import("zod").ZodNumber;
323
+ bytes: import("zod").ZodNumber;
324
+ }, import("zod/v4/core").$strip>;
325
+ quotaLimits: import("zod").ZodObject<{
326
+ maxGenerations: import("zod").ZodNumber;
327
+ maxBytes: import("zod").ZodNumber;
328
+ }, import("zod/v4/core").$strip>;
329
+ fallbackUsed: import("zod").ZodBoolean;
330
+ elapsedMs: import("zod").ZodNumber;
331
+ attempts: import("zod").ZodArray<import("zod").ZodObject<{
332
+ engine: import("zod").ZodString;
333
+ phase: import("zod").ZodOptional<import("zod").ZodUnion<readonly [import("zod").ZodLiteral<"credential">, import("zod").ZodLiteral<"request">, import("zod").ZodLiteral<"parse">]>>;
334
+ code: import("zod").ZodString;
335
+ message: import("zod").ZodOptional<import("zod").ZodString>;
336
+ status: import("zod").ZodOptional<import("zod").ZodNumber>;
337
+ }, import("zod/v4/core").$strip>>;
338
+ }, import("zod/v4/core").$strip>;
260
339
  }>;
261
340
  readonly sourceLocation: Readonly<{
262
341
  file: "src/wire.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"remote.d.ts","sourceRoot":"","sources":["../../../src/client/remote.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAA4B,MAAM,kCAAkC,CAAA;AAE9F,OAAO,KAAK,EAAE,sBAAsB,EAAE,eAAe,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEnH,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,0BAA0B;QAClC,qEAAqE;QACrE,MAAM,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC,CAAA;QACvD,uCAAuC;QACvC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,CAAA;QACnE,iEAAiE;QACjE,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAC,CAAA;QACjG,+BAA+B;QAC/B,eAAe,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAC,CAAA;QACpF,mEAAmE;QACnE,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,oBAAoB,CAAC,CAAC,CAAA;KAC9G;IACD,UAAU,eAAe;QACvB,aAAa,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC,CAAA;QAC9D,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,CAAA;QAC1E,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAC,CAAA;QACxG,sBAAsB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAC,CAAA;QAC3F,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,oBAAoB,CAAC,CAAC,CAAA;KACrH;IACD,UAAU,wBAAwB;QAChC,IAAI,EAAE,0BAA0B,CAAA;KACjC;CACF;AAED,+DAA+D;AAC/D,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGa,CAAA"}
1
+ {"version":3,"file":"remote.d.ts","sourceRoot":"","sources":["../../../src/client/remote.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAA4B,MAAM,kCAAkC,CAAA;AAE9F,OAAO,KAAK,EAAE,sBAAsB,EAAE,eAAe,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEnH,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,0BAA0B;QAClC,qEAAqE;QACrE,MAAM,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC,CAAA;QACvD,uCAAuC;QACvC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,CAAA;QACnE,iEAAiE;QACjE,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAC,CAAA;QACjG,+BAA+B;QAC/B,eAAe,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAC,CAAA;QACpF,mEAAmE;QACnE,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,oBAAoB,CAAC,CAAC,CAAA;KAC9G;IACD,UAAU,eAAe;QACvB,aAAa,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC,CAAA;QAC9D,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,CAAA;QAC1E,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAC,CAAA;QACxG,sBAAsB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAC,CAAA;QAC3F,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,oBAAoB,CAAC,CAAC,CAAA;KACrH;IACD,UAAU,wBAAwB;QAChC,IAAI,EAAE,0BAA0B,CAAA;KACjC;CACF;AAED,+DAA+D;AAC/D,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGa,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/client/styles.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,wEAAwE;AACxE,wBAAgB,iBAAiB,IAAI,MAAM,IAAI,CA+B9C"}
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/client/styles.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH,wEAAwE;AACxE,wBAAgB,iBAAiB,IAAI,MAAM,IAAI,CAwC9C"}
@@ -7,13 +7,21 @@
7
7
  * @module dsh-draw/client/styles
8
8
  */
9
9
  const STYLE_ID = 'dsh-draw-client-styles';
10
+ /**
11
+ * Live installs of this stylesheet. The sheet is shared by every mount of the
12
+ * browser half, so ownership is counted: the node stays as long as any mount
13
+ * is alive, and the LAST disposer removes the node this module inserted.
14
+ * Removing it on the first unmount (or never removing it) is what produced the
15
+ * styles-lost window and the leaked node respectively.
16
+ */
17
+ let liveInstalls = 0;
10
18
  /** Install the scoped stylesheet once; returns the removal disposer. */
11
19
  export function installDrawStyles() {
12
- if (document.getElementById(STYLE_ID) !== null)
13
- return () => undefined;
14
- const style = document.createElement('style');
15
- style.id = STYLE_ID;
16
- style.textContent = `
20
+ liveInstalls += 1;
21
+ if (document.getElementById(STYLE_ID) === null) {
22
+ const style = document.createElement('style');
23
+ style.id = STYLE_ID;
24
+ style.textContent = `
17
25
  .dshdraw-card { display: flex; flex-direction: column; gap: 8px; padding: 4px 0; }
18
26
  .dshdraw-grid { display: flex; flex-wrap: wrap; gap: 8px; }
19
27
  .dshdraw-figure { display: flex; flex-direction: column; gap: 4px; max-width: 320px; }
@@ -36,8 +44,17 @@ export function installDrawStyles() {
36
44
  .dshdraw-badge.warn { color: #9a6700; border-color: #9a6700; }
37
45
  .dshdraw-input { flex: 1; min-width: 180px; border: 1px solid var(--dsh-border, #d0d7de); border-radius: 6px; padding: 4px 8px; font-size: 12px; background: transparent; color: inherit; }
38
46
  `;
39
- document.head.append(style);
47
+ document.head.append(style);
48
+ }
49
+ let disposed = false;
40
50
  return () => {
41
- style.remove();
51
+ if (disposed)
52
+ return;
53
+ disposed = true;
54
+ liveInstalls -= 1;
55
+ if (liveInstalls <= 0) {
56
+ liveInstalls = 0;
57
+ document.getElementById(STYLE_ID)?.remove();
58
+ }
42
59
  };
43
60
  }
@@ -44,6 +44,28 @@ export declare function makeEventGate(knownTypes: ReadonlySet<string>, ignorable
44
44
  * @returns whether the envelope is honored.
45
45
  */
46
46
  export declare function probeIgnorableAppend(): boolean;
47
- /** The gate over the host's known types plus the probed envelope support. */
48
- export declare function makeHostEventGate(): EventGate;
47
+ /**
48
+ * The host gate: the decision function plus the probe result it was built
49
+ * from. The result is recorded on the function instead of being thrown away,
50
+ * so status surfaces can report which regime the session is in.
51
+ */
52
+ export interface HostEventGate extends EventGate {
53
+ /** Whether the mount-time probe found `ignorable` envelope support. */
54
+ readonly ignorableAppend: boolean;
55
+ /** The host-known type set the gate was built over. */
56
+ readonly knownTypes: ReadonlySet<string>;
57
+ }
58
+ /**
59
+ * The gate over the host's known types plus the probed envelope support.
60
+ *
61
+ * A refusal used to be completely silent: the accounting moved to the
62
+ * in-memory fallback ledger and nothing said so. The first refusal now warns
63
+ * once through `warn` (the mount-time probe result is also readable on the
64
+ * returned function), so a degraded session is visible without spamming the
65
+ * log on every commit.
66
+ *
67
+ * @param warn - sink for the one-time degradation warning.
68
+ * @returns the gate carrying its probe result.
69
+ */
70
+ export declare function makeHostEventGate(warn?: (message: string) => void): HostEventGate;
49
71
  //# sourceMappingURL=event-gate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"event-gate.d.ts","sourceRoot":"","sources":["../../src/event-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,2EAA2E;AAC3E,MAAM,WAAW,iBAAiB;IAChC,2CAA2C;IAC3C,MAAM,EAAE,OAAO,CAAA;IACf,oEAAoE;IACpE,SAAS,EAAE,OAAO,CAAA;CACnB;AAED,kDAAkD;AAClD,MAAM,MAAM,SAAS,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,iBAAiB,CAAA;AAE3D;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,eAAe,UAAQ,GAAG,SAAS,CAMjG;AAKD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAoB9C;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,IAAI,SAAS,CAE7C"}
1
+ {"version":3,"file":"event-gate.d.ts","sourceRoot":"","sources":["../../src/event-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,2EAA2E;AAC3E,MAAM,WAAW,iBAAiB;IAChC,2CAA2C;IAC3C,MAAM,EAAE,OAAO,CAAA;IACf,oEAAoE;IACpE,SAAS,EAAE,OAAO,CAAA;CACnB;AAED,kDAAkD;AAClD,MAAM,MAAM,SAAS,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,iBAAiB,CAAA;AAE3D;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,eAAe,UAAQ,GAAG,SAAS,CAMjG;AAKD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAoB9C;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAc,SAAQ,SAAS;IAC9C,uEAAuE;IACvE,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAA;IACjC,uDAAuD;IACvD,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CACzC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAe,GAAG,aAAa,CAqB3F"}
@@ -66,7 +66,35 @@ export function probeIgnorableAppend() {
66
66
  return false;
67
67
  }
68
68
  }
69
- /** The gate over the host's known types plus the probed envelope support. */
70
- export function makeHostEventGate() {
71
- return makeEventGate(KNOWN_SESSION_EVENT_TYPES, probeIgnorableAppend());
69
+ /**
70
+ * The gate over the host's known types plus the probed envelope support.
71
+ *
72
+ * A refusal used to be completely silent: the accounting moved to the
73
+ * in-memory fallback ledger and nothing said so. The first refusal now warns
74
+ * once through `warn` (the mount-time probe result is also readable on the
75
+ * returned function), so a degraded session is visible without spamming the
76
+ * log on every commit.
77
+ *
78
+ * @param warn - sink for the one-time degradation warning.
79
+ * @returns the gate carrying its probe result.
80
+ */
81
+ export function makeHostEventGate(warn = () => { }) {
82
+ const ignorableAppend = probeIgnorableAppend();
83
+ const gate = makeEventGate(KNOWN_SESSION_EVENT_TYPES, ignorableAppend);
84
+ let warned = false;
85
+ const hostGate = ((type) => {
86
+ const decision = gate(type);
87
+ if (!decision.append && !warned) {
88
+ warned = true;
89
+ warn('dsh-draw: this host neither knows the draw/generated event type nor honors the ignorable envelope, '
90
+ + 'so the audit event is not written; the in-memory fallback ledger keeps quota exact for this session '
91
+ + 'and resets when the session restarts');
92
+ }
93
+ return decision;
94
+ });
95
+ Object.defineProperties(hostGate, {
96
+ ignorableAppend: { value: ignorableAppend, enumerable: true },
97
+ knownTypes: { value: KNOWN_SESSION_EVENT_TYPES, enumerable: true },
98
+ });
99
+ return hostGate;
72
100
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAMlD,OAAO,EAAE,MAAM,EAAiB,MAAM,aAAa,CAAA;AAQnD,eAAO,MAAM,IAAI,aAAa,CAAA;AAE9B,oEAAoE;AACpE,eAAO,MAAM,MAAM,UAAY,CAAA;AAK/B,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,MAAM,IAAI,UAAU,EAAE,KAAK,cAAc,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAChI,OAAO,EAAE,YAAY,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAA;AAClG,OAAO,EAAE,MAAM,EAAE,KAAK,SAAS,EAAE,KAAK,iBAAiB,EAAE,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAA;AAClI,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACjI,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAA;AAC9F,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAClG,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAC9F,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,eAAe,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAA;AAClH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAClF,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACzJ,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,KAAK,SAAS,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAChI,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAK7G;;;;;;;GAOG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwCvE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAMlD,OAAO,EAAE,MAAM,EAAiB,MAAM,aAAa,CAAA;AAQnD,eAAO,MAAM,IAAI,aAAa,CAAA;AAE9B,oEAAoE;AACpE,eAAO,MAAM,MAAM,UAAY,CAAA;AAK/B,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,MAAM,IAAI,UAAU,EAAE,KAAK,cAAc,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAChI,OAAO,EAAE,YAAY,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAA;AAClG,OAAO,EAAE,MAAM,EAAE,KAAK,SAAS,EAAE,KAAK,iBAAiB,EAAE,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAA;AAClI,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACjI,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAA;AAC9F,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAClG,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAC9F,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,eAAe,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAA;AAClH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAClF,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACzJ,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,KAAK,SAAS,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAChI,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAK7G;;;;;;;GAOG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDvE"}
@@ -82,10 +82,27 @@ export async function apply(ctx, config) {
82
82
  },
83
83
  attachments: () => ctx.get('attachments'),
84
84
  sessions: () => ctx.get('sessions'),
85
- }, { gate: makeHostEventGate(), warn: (message) => logger.warn(message) });
85
+ }, { gate: makeHostEventGate((message) => logger.warn(message)), warn: (message) => logger.warn(message) });
86
86
  // Service Provider — ctx.tools.register mounts the image_generate tool and
87
87
  // the `draw` Remote service; every registration is an effect on this fiber.
88
88
  ctx.effect(() => ctx.tools.register(imageGenerateTool(drawer, resolved)), 'dsh-draw: image_generate tool');
89
- await ctx.plugin(DrawService, { config: resolved, router, drawer, credentials: credentials() });
89
+ // A02: the mount is awaited, so hold it in an effect registered BEFORE the
90
+ // await. A disposal that lands while DrawService is still mounting then
91
+ // unwinds the child fiber through the effect instead of leaving a
92
+ // half-applied mount; the post-await fiber check keeps the success log from
93
+ // claiming a mount that was already torn down, and a real mount failure
94
+ // still propagates.
95
+ const serviceFiber = ctx.plugin(DrawService, { config: resolved, router, drawer, credentials: credentials() });
96
+ ctx.effect(() => () => { void serviceFiber.dispose(); }, 'dsh-draw: draw service');
97
+ try {
98
+ await serviceFiber;
99
+ }
100
+ catch (error) {
101
+ if (ctx.fiber.uid === null)
102
+ return; // unwound by our own disposer, not a mount failure
103
+ throw error;
104
+ }
105
+ if (ctx.fiber.uid === null)
106
+ return;
90
107
  logger.info(`image generation enabled: ${resolved.engines.map(engine => engine.id).join(', ')} (preferred ${resolved.defaultEngine})`);
91
108
  }
@@ -1 +1 @@
1
- {"version":3,"file":"session-events.d.ts","sourceRoot":"","sources":["../../src/session-events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhD,OAAO,QAAQ,gCAAgC,CAAC;IAC9C,UAAU,eAAe;QACvB;;;WAGG;QACH,gBAAgB,EAAE,kBAAkB,CAAA;KACrC;CACF;AAED,qDAAqD;AACrD,MAAM,WAAW,kBAAkB;IACjC,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAA;IACd,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,yEAAyE;IACzE,MAAM,EAAE,MAAM,GAAG,YAAY,CAAA;IAC7B,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAA;IACd,qDAAqD;IACrD,IAAI,EAAE,QAAQ,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,CAAA;IAClD,6CAA6C;IAC7C,OAAO,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAA;IAC3C,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAA;IACb,8CAA8C;IAC9C,aAAa,EAAE,SAAS,MAAM,EAAE,CAAA;IAChC,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,kBAAkB;;;;;;;;;EAE9E;AAaD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAiBvI;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,kBAAkB,EAAE,CAE3F;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,OAAO,0BAA0B,EAAE,YAAY,CAAC,gBAAgB,CAAC,EAAE,CAOlI"}
1
+ {"version":3,"file":"session-events.d.ts","sourceRoot":"","sources":["../../src/session-events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhD,OAAO,QAAQ,gCAAgC,CAAC;IAC9C,UAAU,eAAe;QACvB;;;WAGG;QACH,gBAAgB,EAAE,kBAAkB,CAAA;KACrC;CACF;AAED,qDAAqD;AACrD,MAAM,WAAW,kBAAkB;IACjC,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAA;IACd,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,yEAAyE;IACzE,MAAM,EAAE,MAAM,GAAG,YAAY,CAAA;IAC7B,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAA;IACd,qDAAqD;IACrD,IAAI,EAAE,QAAQ,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,CAAA;IAClD,6CAA6C;IAC7C,OAAO,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAA;IAC3C,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAA;IACb,8CAA8C;IAC9C,aAAa,EAAE,SAAS,MAAM,EAAE,CAAA;IAChC,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,kBAAkB;;;;;;;;;EAE9E;AAaD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAiBvI;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,kBAAkB,EAAE,CAE3F;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,OAAO,0BAA0B,EAAE,YAAY,CAAC,gBAAgB,CAAC,EAAE,CAclI"}
@@ -87,8 +87,15 @@ export function fallbackDrawGeneratedEvents(session) {
87
87
  * @returns the accounting events.
88
88
  */
89
89
  export function drawGeneratedEvents(session) {
90
- // alpha.5 renamed the Session.events getter to snapshotEvents(); the peer
91
- // floor (>=0.1.0-rc.8) still exposes .events, so detect at runtime.
90
+ // `Session.snapshotEvents()` is deprecated on the 0.1.6 line ("new calls are
91
+ // prohibited"), and this is an existing call. The migration target is the
92
+ // optional `sessionQuery` service (`readSession(sessionId).events`, the
93
+ // complete raw log — `readSurface` would NOT do: draw/generated is a
94
+ // non-surface audit type). Migrating it is not a local edit: quota folding
95
+ // (`quotaState` / `checkQuotaGenerations` / `checkQuotaBytes`) is synchronous
96
+ // and consumed by the tool path, the Remote status snapshot and the card, so
97
+ // the move turns that whole API async. Tracked for a dedicated card; the
98
+ // `.events` fallback below stays for the pre-alpha.5 peer floor.
92
99
  const snapshot = typeof session.snapshotEvents === 'function'
93
100
  ? session.snapshotEvents()
94
101
  : session.events;