@deepseek-ai/dsh-experimental-webworker-runtime 0.1.6-alpha.1 → 0.1.7-alpha.1

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.
@@ -3,7 +3,7 @@
3
3
  * @module @deepseek-ai/dsh-experimental-webworker-runtime
4
4
  */
5
5
  export { createAlsRuntime, type AlsCausality, type AlsRuntime, type AlsSnapshot, type AlsToken, } from './polyfill/async-context/als-runtime.ts';
6
- export { parseInboundFrame, type TunnelAbortFrame, type TunnelInboundFrame, type TunnelOutboundFrame, type TunnelRequestFrame, type TunnelRequestId, type TunnelResponseChunkFrame, type TunnelResponseEndFrame, type TunnelResponseErrorFrame, type TunnelResponseFrame, type TunnelResponseHeadFrame, type TunnelStreamEndFrame, type TunnelStreamErrorFrame, type TunnelStreamItemFrame, type TunnelStreamOpenFrame, } from './transport/frames.ts';
6
+ export { parseInboundFrame, type TunnelAbortFrame, type TunnelInboundFrame, type TunnelOutboundFrame, type TunnelRequestFrame, type TunnelRequestId, type TunnelResponseChunkFrame, type TunnelResponseEndFrame, type TunnelResponseErrorFrame, type TunnelResponseFrame, type TunnelResponseHeadFrame, type TunnelStreamEndFrame, type TunnelStreamErrorFrame, type TunnelStreamUplinkEndFrame, type TunnelStreamUplinkItemFrame, type TunnelStreamItemFrame, type TunnelStreamOpenFrame, } from './transport/frames.ts';
7
7
  export { DEFAULT_CONDITIONS, requireActiveModuleLoader, setActiveModuleLoader, WorkerModuleLoader, type Resolution, type StaticModuleFactory, type WorkerModuleLoaderOptions, type WorkerRequire, } from './module-system/module-loader.ts';
8
8
  export * as posixPath from './module-system/posix-path.ts';
9
9
  export { MODULE_PROXIES, MODULE_PROXY_PREFIXES } from './module-proxies.ts';
@@ -0,0 +1,11 @@
1
+ /** Promise-based stream completion and pipelines from the shared readable-stream implementation. */
2
+ import { promises } from '../stream.ts';
3
+ /** Shared stream completion promise, including abort and listener cleanup options. */
4
+ export declare const finished: typeof import("stream/promises").finished;
5
+ /** Shared stream pipeline promise, including backpressure and error propagation. */
6
+ export declare const pipeline: typeof import("stream/promises").pipeline;
7
+ /** CommonJS interop marker consumed by the worker module loader. */
8
+ export declare const __esModule = true;
9
+ /** CommonJS-compatible promise namespace. */
10
+ export default promises;
11
+ //# sourceMappingURL=promises.d.ts.map
@@ -30,7 +30,7 @@ export declare function inspect(value: unknown): string;
30
30
  */
31
31
  export declare function format(template: unknown, ...args: unknown[]): string;
32
32
  /**
33
- * Structural deep equality, as `isDeepStrictEqual` defines it for plain data.
33
+ * Structural deep equality over own enumerable properties, as `isDeepStrictEqual` defines it for plain data.
34
34
  * @param left - first value.
35
35
  * @param right - second value.
36
36
  * @returns true when both sides are structurally identical.
@@ -0,0 +1,3 @@
1
+ /** Refuse external package commands in the worker host. */
2
+ export declare const execa: (...args: never[]) => never;
3
+ //# sourceMappingURL=execa.d.ts.map
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Refuse converter creation with the kit's unavailable error code.
3
+ * @returns A rejected promise consumed by the Host office-to-pdf provider.
4
+ */
5
+ export declare function createConverter(): Promise<never>;
6
+ //# sourceMappingURL=libreoffice-kit.d.ts.map
@@ -9,7 +9,7 @@ export declare const DSH_ROOT = "/dsh";
9
9
  export declare const DSH_HOME = "/dsh/home";
10
10
  /** Flat, symlink-free package tree resolved by the worker module loader. */
11
11
  export declare const DSH_NODE_MODULES = "/dsh/node_modules";
12
- /** Directory holding the composed cordis.yml and the agent-preset tree. */
12
+ /** Directory holding the composed cordis.yml. */
13
13
  export declare const DSH_CONFIG = "/dsh/config";
14
14
  /** Default (empty) workspace directory. */
15
15
  export declare const DSH_WORKSPACE = "/dsh/workspace";
@@ -21,6 +21,17 @@ export interface TunnelStreamOpenFrame {
21
21
  readonly endpoint: string;
22
22
  readonly payload: unknown;
23
23
  }
24
+ /** One uplink item for an open Remote stream; `value` absent and `undefined` are equivalent. */
25
+ export interface TunnelStreamUplinkItemFrame {
26
+ readonly t: 'stream-uplink-item';
27
+ readonly id: TunnelRequestId;
28
+ readonly value?: unknown;
29
+ }
30
+ /** Page-side half-close of a Remote stream's uplink. */
31
+ export interface TunnelStreamUplinkEndFrame {
32
+ readonly t: 'stream-uplink-end';
33
+ readonly id: TunnelRequestId;
34
+ }
24
35
  /** Page-side cancellation of an in-flight request or stream. */
25
36
  export interface TunnelAbortFrame {
26
37
  readonly t: 'abort';
@@ -37,7 +48,7 @@ export interface TunnelInitFrame {
37
48
  readonly overlays: readonly string[];
38
49
  }
39
50
  /** Every frame the page sends the worker. */
40
- export type TunnelInboundFrame = TunnelInitFrame | TunnelRequestFrame | TunnelStreamOpenFrame | TunnelAbortFrame;
51
+ export type TunnelInboundFrame = TunnelInitFrame | TunnelRequestFrame | TunnelStreamOpenFrame | TunnelStreamUplinkItemFrame | TunnelStreamUplinkEndFrame | TunnelAbortFrame;
41
52
  /** Complete response for unary requests and static files. */
42
53
  export interface TunnelResponseFrame {
43
54
  readonly t: 'res';
@@ -47,8 +47,8 @@ export interface TunnelSeams {
47
47
  readonly directFetch: (request: Request) => Promise<Response>;
48
48
  /** Boot payload for `GET /__boot__`: the structured index injection table. */
49
49
  readonly bootPayload: () => unknown;
50
- /** Open one decoded Gateway Remote stream without another network carrier. */
51
- readonly openStream: (endpoint: string, payload: unknown, signal: AbortSignal) => Promise<AsyncIterable<unknown>>;
50
+ /** Open one decoded Gateway Remote stream without another network carrier; `uplink` carries the page's items. */
51
+ readonly openStream: (endpoint: string, payload: unknown, uplink: AsyncIterable<unknown>, signal: AbortSignal) => Promise<AsyncIterable<unknown>>;
52
52
  /** Convert a Gateway stream failure to stable Client fields. */
53
53
  readonly streamFailure: (error: unknown) => {
54
54
  readonly code: string;
@@ -85,6 +85,8 @@ export declare class TunnelServer {
85
85
  private readonly unaryApiLane;
86
86
  private readonly queue;
87
87
  private readonly inFlight;
88
+ /** Uplinks of accepted `stream-open` frames, buffering items that arrive before or while the stream serves. */
89
+ private readonly uplinks;
88
90
  private seams;
89
91
  private failure;
90
92
  private listener;
@@ -109,6 +111,8 @@ export declare class TunnelServer {
109
111
  private refuse;
110
112
  private dispatchFrame;
111
113
  private serveStream;
114
+ /** The stream is over: settle any Host read still waiting on its uplink and stop buffering. */
115
+ private dropUplink;
112
116
  private sinkFor;
113
117
  /** The page sends an absolute URL; route handlers read `req.url` as a path. */
114
118
  private pathFrame;
@@ -17,8 +17,8 @@
17
17
  *
18
18
  * The tree itself boots through the host's own `boot()` glue loaded from the
19
19
  * image, so entry mounting, the activation audit, and its diagnostics are the
20
- * same code the Node deployment runs. Only the module seam and the command line
21
- * are supplied from here.
20
+ * same code the Node deployment runs. The Worker supplies module loading,
21
+ * profile locations, and the command line.
22
22
  * @module @deepseek-ai/dsh-experimental-webworker-runtime/src/worker-host
23
23
  */
24
24
  import { WorkerModuleLoader, type StaticModuleFactory } from './module-system/module-loader.ts';
package/lib/worker.js CHANGED
@@ -717,6 +717,15 @@ function parseInboundFrame(data) {
717
717
  t: "abort",
718
718
  id
719
719
  };
720
+ if (frame.t === "stream-uplink-end") return {
721
+ t: "stream-uplink-end",
722
+ id
723
+ };
724
+ if (frame.t === "stream-uplink-item") return {
725
+ t: "stream-uplink-item",
726
+ id,
727
+ value: frame.value
728
+ };
720
729
  if (frame.t === "stream-open") {
721
730
  if (typeof frame.endpoint !== "string" || frame.endpoint.length === 0) throw new Error(`webworker tunnel: stream ${String(id)} needs a non-empty endpoint`);
722
731
  return {
@@ -962,6 +971,61 @@ var BufferedSink = class {
962
971
  for (const call of this.calls.splice(0)) call();
963
972
  }
964
973
  };
974
+ /** Uplink items of one worker-local logical stream, read once by the Host method as its `uplink`. */
975
+ var TunnelUplink = class {
976
+ items = [];
977
+ ended = false;
978
+ closed = false;
979
+ wake;
980
+ push(value) {
981
+ if (this.ended || this.closed) return;
982
+ this.items.push(value);
983
+ this.signal();
984
+ }
985
+ /** Page half-close or stream end; buffered items still drain. */
986
+ end() {
987
+ this.ended = true;
988
+ this.signal();
989
+ }
990
+ [Symbol.asyncIterator]() {
991
+ return this;
992
+ }
993
+ async next() {
994
+ while (true) {
995
+ if (this.closed) return {
996
+ value: void 0,
997
+ done: true
998
+ };
999
+ if (this.items.length > 0) return {
1000
+ value: this.items.shift(),
1001
+ done: false
1002
+ };
1003
+ if (this.ended) return {
1004
+ value: void 0,
1005
+ done: true
1006
+ };
1007
+ if (this.wake !== void 0) throw new Error("webworker tunnel: stream uplink has one pending read");
1008
+ await new Promise((resolve) => {
1009
+ this.wake = resolve;
1010
+ });
1011
+ }
1012
+ }
1013
+ /** The Host stopped reading: buffered and later items are dropped. */
1014
+ return() {
1015
+ this.closed = true;
1016
+ this.items.length = 0;
1017
+ this.signal();
1018
+ return Promise.resolve({
1019
+ value: void 0,
1020
+ done: true
1021
+ });
1022
+ }
1023
+ signal() {
1024
+ const wake = this.wake;
1025
+ this.wake = void 0;
1026
+ wake?.();
1027
+ }
1028
+ };
965
1029
  /** One tunnel per worker; wire {@link TunnelServer.handleMessage} to `onmessage` first. */
966
1030
  var TunnelServer = class {
967
1031
  port;
@@ -970,6 +1034,8 @@ var TunnelServer = class {
970
1034
  unaryApiLane;
971
1035
  queue = [];
972
1036
  inFlight = /* @__PURE__ */ new Map();
1037
+ /** Uplinks of accepted `stream-open` frames, buffering items that arrive before or while the stream serves. */
1038
+ uplinks = /* @__PURE__ */ new Map();
973
1039
  seams;
974
1040
  failure;
975
1041
  listener;
@@ -986,9 +1052,18 @@ var TunnelServer = class {
986
1052
  handleMessage(data) {
987
1053
  const frame = parseInboundFrame(data);
988
1054
  if (frame.t === "init") throw new Error("webworker tunnel: duplicate init frame; the tunnel is already open");
1055
+ if (frame.t === "stream-uplink-item") {
1056
+ this.uplinks.get(frame.id)?.push(frame.value);
1057
+ return;
1058
+ }
1059
+ if (frame.t === "stream-uplink-end") {
1060
+ this.uplinks.get(frame.id)?.end();
1061
+ return;
1062
+ }
989
1063
  if (frame.t === "abort") {
990
1064
  this.inFlight.get(frame.id)?.abort();
991
1065
  this.inFlight.delete(frame.id);
1066
+ this.dropUplink(frame.id);
992
1067
  const queued = this.queue.findIndex((request) => request.id === frame.id);
993
1068
  if (queued !== -1) this.queue.splice(queued, 1);
994
1069
  return;
@@ -997,6 +1072,7 @@ var TunnelServer = class {
997
1072
  this.refuse(frame, this.failure);
998
1073
  return;
999
1074
  }
1075
+ if (frame.t === "stream-open") this.uplinks.set(frame.id, new TunnelUplink());
1000
1076
  if (this.seams === void 0) {
1001
1077
  this.queue.push(frame);
1002
1078
  return;
@@ -1027,6 +1103,7 @@ var TunnelServer = class {
1027
1103
  }
1028
1104
  refuse(frame, message) {
1029
1105
  if (frame.t === "stream-open") {
1106
+ this.dropUplink(frame.id);
1030
1107
  this.send({
1031
1108
  t: "stream-error",
1032
1109
  id: frame.id,
@@ -1057,12 +1134,13 @@ var TunnelServer = class {
1057
1134
  return;
1058
1135
  }
1059
1136
  const seams = this.seams;
1137
+ const uplink = this.uplinks.get(frame.id) ?? new TunnelUplink();
1060
1138
  const controller = new AbortController();
1061
1139
  this.inFlight.set(frame.id, { abort: () => {
1062
1140
  controller.abort();
1063
1141
  } });
1064
1142
  try {
1065
- const source = await seams.openStream(frame.endpoint, frame.payload, controller.signal);
1143
+ const source = await seams.openStream(frame.endpoint, frame.payload, uplink, controller.signal);
1066
1144
  for await (const value of source) {
1067
1145
  if (controller.signal.aborted) return;
1068
1146
  this.send({
@@ -1089,8 +1167,15 @@ var TunnelServer = class {
1089
1167
  }
1090
1168
  } finally {
1091
1169
  this.inFlight.delete(frame.id);
1170
+ this.dropUplink(frame.id);
1092
1171
  }
1093
1172
  }
1173
+ /** The stream is over: settle any Host read still waiting on its uplink and stop buffering. */
1174
+ dropUplink(id) {
1175
+ const uplink = this.uplinks.get(id);
1176
+ this.uplinks.delete(id);
1177
+ uplink?.end();
1178
+ }
1094
1179
  sinkFor(id) {
1095
1180
  const send = this.send.bind(this);
1096
1181
  const inFlight = this.inFlight;
@@ -2526,8 +2611,10 @@ function createWorkerHost(options) {
2526
2611
  const require = loader.requireFrom(dirname$1(configPath));
2527
2612
  const appBoot = require("@deepseek-ai/dsh-app-boot");
2528
2613
  const cmdline = require("@deepseek-ai/dsh-cmdline");
2529
- const { patches, presetOverlay } = bootPatches(loader, mounted, configPath, root);
2530
- const ctx = await appBoot.boot("dsh-webworker", configPath, patches, (hostCtx) => {
2614
+ const { patches, profile } = bootPatches(loader, mounted, configPath, root);
2615
+ const profileConfig = join$1(profile.dir, "cordis.yml");
2616
+ const ctx = await appBoot.boot("dsh-webworker", profileConfig, patches, (hostCtx) => {
2617
+ hostCtx.provide("profileContext", profile);
2531
2618
  hostCtx.loader.internal = loader.internal;
2532
2619
  installLogSink(hostCtx, require);
2533
2620
  cmdline.provideCmdline(hostCtx, {
@@ -2550,11 +2637,11 @@ function createWorkerHost(options) {
2550
2637
  if (typertGateway === void 0) throw new Error("webworker host: the tree activated without a typertGateway service");
2551
2638
  const handler = connection.createSharedFetchHandler("/api");
2552
2639
  const usage = loader.usage();
2553
- console.info(`webworker host: tree active (modules=${String(usage.modules)}, data overlays=${String(overlays.length)}, preset root overlay=${presetOverlay ? "applied" : "already in roster"}, direct lane=connection.createSharedFetchHandler, als causality=${options.alsCausality === void 0 ? "inert" : "snapshot/restore"}, image lowering=${LOWERING_VERSION})`);
2640
+ console.info(`webworker host: tree active (modules=${String(usage.modules)}, data overlays=${String(overlays.length)}, direct lane=connection.createSharedFetchHandler, als causality=${options.alsCausality === void 0 ? "inert" : "snapshot/restore"}, image lowering=${LOWERING_VERSION})`);
2554
2641
  tunnel.serve({
2555
2642
  directFetch: (request) => handler.fetch(request),
2556
2643
  bootPayload: () => readBootPayload(ctx),
2557
- openStream: typertGateway.wireStream.open,
2644
+ openStream: (endpoint, payload, uplink, signal) => typertGateway.wireStream.open(endpoint, payload, uplink, void 0, signal),
2558
2645
  streamFailure: typertGateway.wireStream.failure
2559
2646
  });
2560
2647
  } catch (reason) {
@@ -2626,30 +2713,22 @@ function requireLoweredImage(vfs, path) {
2626
2713
  if (lowered !== "dsh-worker-transform/1") throw new Error(`webworker host: image was lowered by ${String(lowered)}, this build runs ${LOWERING_VERSION}; rebuild the image`);
2627
2714
  }
2628
2715
  /**
2629
- * The shipped preset root, as the application layer that owns the composition
2630
- * supplies it.
2631
- *
2632
- * A launcher appends this root itself rather than writing it into the roster —
2633
- * `apps/cli` does it in `composeProfile` (`profile-boot.ts:159-166`) because only
2634
- * the application knows where its own presets sit. The worker's presets travel
2635
- * in the image, so the same overlay names their virtual path. Patching replaces
2636
- * a row's whole `config`, so the current one is read and spread, and a roster
2637
- * that already names roots keeps them.
2716
+ * Prepare an editable VFS profile from the packed rows and deployment overlays.
2717
+ * ConfigEditor writes overrides beside the insertion rows; reconciliation starts
2718
+ * at the empty profile root and retains the Worker deployment overlays.
2638
2719
  * @param loader - Module loader, for the image's YAML reader.
2639
2720
  * @param vfs - Filesystem holding the composed configuration.
2640
2721
  * @param configPath - Composed configuration path.
2641
2722
  * @param root - Virtual root.
2642
- * @returns Boot patches (preset root overlay, frontend serving off) and
2643
- * whether the preset overlay was applied.
2723
+ * @returns Profile locations and effective boot patches.
2644
2724
  */
2645
2725
  function bootPatches(loader, vfs, configPath, root) {
2646
2726
  const text = vfs.readFileSync(configPath, "utf8");
2727
+ const include = loader.load(loader.resolve("@deepseek-ai/cordis-plugin-include", root));
2728
+ const yaml = loader.load(loader.resolve("js-yaml", root));
2647
2729
  let rows;
2648
2730
  if (configPath.endsWith(".json")) rows = JSON.parse(text);
2649
- else {
2650
- const include = loader.load(loader.resolve("@deepseek-ai/cordis-plugin-include", root));
2651
- rows = loader.load(loader.resolve("js-yaml", root)).load(text, { schema: include.entryListSchema });
2652
- }
2731
+ else rows = yaml.load(text, { schema: include.entryListSchema });
2653
2732
  const find = (entries, id) => {
2654
2733
  if (!Array.isArray(entries)) return void 0;
2655
2734
  for (const entry of entries) {
@@ -2660,21 +2739,10 @@ function bootPatches(loader, vfs, configPath, root) {
2660
2739
  };
2661
2740
  const configOf = (row) => typeof row.config === "object" && row.config !== null && !Array.isArray(row.config) ? row.config : {};
2662
2741
  const patches = [];
2663
- let presetOverlay = false;
2664
- const presets = find(rows, "agent-presets");
2665
- if (presets !== void 0 && configOf(presets).roots === void 0) {
2666
- presetOverlay = true;
2667
- patches.push({
2668
- id: "agent-presets",
2669
- config: {
2670
- ...configOf(presets),
2671
- roots: [{
2672
- path: join$1(root, "config/agent-presets"),
2673
- trust: "system"
2674
- }]
2675
- }
2676
- });
2677
- }
2742
+ for (const id of ["hmr", "plugin-manager"]) if (find(rows, id) !== void 0) patches.push({
2743
+ id,
2744
+ disabled: true
2745
+ });
2678
2746
  const jsonl = find(rows, "session-persistence-jsonl");
2679
2747
  if (jsonl !== void 0) patches.push({
2680
2748
  id: "session-persistence-jsonl",
@@ -2683,9 +2751,24 @@ function bootPatches(loader, vfs, configPath, root) {
2683
2751
  compression: "none"
2684
2752
  }
2685
2753
  });
2754
+ const dir = join$1(root, IMAGE_HOME_DIRECTORY, "profiles/preview");
2755
+ const profile = {
2756
+ name: "preview",
2757
+ dir,
2758
+ patchPath: join$1(dir, "cordis.patch.yml"),
2759
+ installAnchor: join$1(dir, "package.json"),
2760
+ cwd: root,
2761
+ home: join$1(root, IMAGE_HOME_DIRECTORY),
2762
+ startedBundles: [],
2763
+ overlays: patches,
2764
+ telemetryDisabledEnv: void 0
2765
+ };
2766
+ vfs.seed(join$1(dir, "package.json"), "{\"private\":true,\"dsh\":{\"profile\":{\"bundles\":[]}}}\n");
2767
+ vfs.seed(join$1(dir, "cordis.yml"), "[]\n");
2768
+ if (!vfs.existsSync(profile.patchPath)) vfs.seed(profile.patchPath, yaml.dump([{ insert: rows }], { schema: include.entryListSchema }));
2686
2769
  return {
2687
- patches,
2688
- presetOverlay
2770
+ patches: loader.load(loader.resolve("@deepseek-ai/dsh-app-boot", root)).readProfilePatches("dsh-webworker", profile),
2771
+ profile
2689
2772
  };
2690
2773
  }
2691
2774
  /**
@@ -5782,15 +5865,15 @@ var crypto_default = {
5782
5865
  * reaching public-address preflight must fail loud instead of inventing an
5783
5866
  * address or bypassing the native HTTP provider's SSRF policy.
5784
5867
  */
5785
- var promises_exports$2 = /* @__PURE__ */ __exportAll({
5868
+ var promises_exports$3 = /* @__PURE__ */ __exportAll({
5786
5869
  __esModule: () => true,
5787
- default: () => promises_default$2,
5870
+ default: () => promises_default$3,
5788
5871
  lookup: () => lookup
5789
5872
  });
5790
5873
  /** DNS lookup (unavailable in the worker host). */
5791
5874
  const lookup = notImplementedFail("node:dns/promises", "lookup");
5792
5875
  /** CommonJS default export: the members `require()` hands a caller of this module. */
5793
- var promises_default$2 = { lookup };
5876
+ var promises_default$3 = { lookup };
5794
5877
  //#endregion
5795
5878
  //#region src/node/builtin_modules/implemented/events.ts
5796
5879
  var events_exports = /* @__PURE__ */ __exportAll({
@@ -11044,18 +11127,18 @@ var stream_exports = /* @__PURE__ */ __exportAll({
11044
11127
  compose: () => compose,
11045
11128
  default: () => streamDefault,
11046
11129
  destroy: () => destroy,
11047
- finished: () => finished,
11130
+ finished: () => finished$1,
11048
11131
  getDefaultHighWaterMark: () => getDefaultHighWaterMark,
11049
11132
  isDestroyed: () => isDestroyed,
11050
11133
  isDisturbed: () => isDisturbed,
11051
11134
  isErrored: () => isErrored,
11052
11135
  isReadable: () => isReadable,
11053
11136
  isWritable: () => isWritable,
11054
- pipeline: () => pipeline,
11137
+ pipeline: () => pipeline$1,
11055
11138
  promises: () => promises$1,
11056
11139
  setDefaultHighWaterMark: () => setDefaultHighWaterMark
11057
11140
  });
11058
- const { Duplex, PassThrough, Readable, Stream: StreamBase, Transform, Writable, addAbortSignal, compose, destroy, finished, isDisturbed, isErrored, isReadable, pipeline, promises: promises$1 } = (/* @__PURE__ */ __toESM(require_browser(), 1)).default;
11141
+ const { Duplex, PassThrough, Readable, Stream: StreamBase, Transform, Writable, addAbortSignal, compose, destroy, finished: finished$1, isDisturbed, isErrored, isReadable, pipeline: pipeline$1, promises: promises$1 } = (/* @__PURE__ */ __toESM(require_browser(), 1)).default;
11059
11142
  const { getDefaultHighWaterMark, isDestroyed, isWritable, setDefaultHighWaterMark } = StreamBase;
11060
11143
  if (getDefaultHighWaterMark(false) !== 64 * 1024) setDefaultHighWaterMark(false, 64 * 1024);
11061
11144
  /**
@@ -12609,7 +12692,7 @@ var fs_default = {
12609
12692
  * member set is checked against Node where it is built, on `promises` in
12610
12693
  * `../fs.ts`.
12611
12694
  */
12612
- var promises_exports$1 = /* @__PURE__ */ __exportAll({
12695
+ var promises_exports$2 = /* @__PURE__ */ __exportAll({
12613
12696
  Dirent: () => Dirent,
12614
12697
  __esModule: () => true,
12615
12698
  access: () => access,
@@ -12617,7 +12700,7 @@ var promises_exports$1 = /* @__PURE__ */ __exportAll({
12617
12700
  chmod: () => chmod,
12618
12701
  constants: () => constants$2,
12619
12702
  cp: () => cp$1,
12620
- default: () => promises_default$1,
12703
+ default: () => promises_default$2,
12621
12704
  link: () => link,
12622
12705
  lstat: () => lstat,
12623
12706
  mkdir: () => mkdir$1,
@@ -12637,7 +12720,7 @@ var promises_exports$1 = /* @__PURE__ */ __exportAll({
12637
12720
  });
12638
12721
  /** The promise members of the VFS bridge, as `node:fs/promises` names them. */
12639
12722
  const { readFile, writeFile, appendFile, mkdir: mkdir$1, mkdtemp, readdir, stat: stat$1, lstat, realpath, rm: rm$1, unlink, rename, access, chmod, cp: cp$1, link, open: open$1, opendir, truncate, watch, constants: constants$2 } = promises;
12640
- var promises_default$1 = promises;
12723
+ var promises_default$2 = promises;
12641
12724
  //#endregion
12642
12725
  //#region src/node/builtin_modules/implemented/http.ts
12643
12726
  var http_exports = /* @__PURE__ */ __exportAll({
@@ -13035,6 +13118,21 @@ var perf_hooks_default = {
13035
13118
  PerformanceObserver
13036
13119
  };
13037
13120
  //#endregion
13121
+ //#region src/node/builtin_modules/implemented/stream/promises.ts
13122
+ /** Promise-based stream completion and pipelines from the shared readable-stream implementation. */
13123
+ var promises_exports$1 = /* @__PURE__ */ __exportAll({
13124
+ __esModule: () => true,
13125
+ default: () => promises_default$1,
13126
+ finished: () => finished,
13127
+ pipeline: () => pipeline
13128
+ });
13129
+ /** Shared stream completion promise, including abort and listener cleanup options. */
13130
+ const finished = promises$1.finished;
13131
+ /** Shared stream pipeline promise, including backpressure and error propagation. */
13132
+ const pipeline = promises$1.pipeline;
13133
+ /** CommonJS-compatible promise namespace. */
13134
+ var promises_default$1 = promises$1;
13135
+ //#endregion
13038
13136
  //#region src/node/builtin_modules/implemented/timers/promises.ts
13039
13137
  var promises_exports = /* @__PURE__ */ __exportAll({
13040
13138
  __esModule: () => true,
@@ -13255,7 +13353,7 @@ function format(template, ...args) {
13255
13353
  return rest.length === 0 ? substituted : `${substituted} ${rest.map((value) => inspect(value)).join(" ")}`;
13256
13354
  }
13257
13355
  /**
13258
- * Structural deep equality, as `isDeepStrictEqual` defines it for plain data.
13356
+ * Structural deep equality over own enumerable properties, as `isDeepStrictEqual` defines it for plain data.
13259
13357
  * @param left - first value.
13260
13358
  * @param right - second value.
13261
13359
  * @returns true when both sides are structurally identical.
@@ -13267,7 +13365,7 @@ function isDeepStrictEqual(left, right) {
13267
13365
  const leftKeys = Object.keys(left);
13268
13366
  const rightKeys = Object.keys(right);
13269
13367
  if (leftKeys.length !== rightKeys.length) return false;
13270
- return leftKeys.every((key) => key in right && isDeepStrictEqual(left[key], right[key]));
13368
+ return leftKeys.every((key) => Object.hasOwn(right, key) && isDeepStrictEqual(left[key], right[key]));
13271
13369
  }
13272
13370
  /** Runtime type predicates (`node:util/types`), checked against the Node module of that name. */
13273
13371
  const types$1 = {
@@ -21402,6 +21500,17 @@ const koffi = {
21402
21500
  call: notImplementedFail(MODULE$3, "call")
21403
21501
  };
21404
21502
  //#endregion
21503
+ //#region src/node/external_packages/libreoffice-kit.ts
21504
+ /** Office conversion requires a Node Host; the browser preview carries no engine assets. */
21505
+ var libreoffice_kit_exports = /* @__PURE__ */ __exportAll({ createConverter: () => createConverter });
21506
+ /**
21507
+ * Refuse converter creation with the kit's unavailable error code.
21508
+ * @returns A rejected promise consumed by the Host office-to-pdf provider.
21509
+ */
21510
+ function createConverter() {
21511
+ return Promise.reject(Object.assign(notAvailableError("@deepseek-ai/libreoffice-kit", "createConverter"), { code: "unavailable" }));
21512
+ }
21513
+ //#endregion
21405
21514
  //#region src/node/external_packages/node-pty.ts
21406
21515
  /**
21407
21516
  * `node-pty` stub: pseudo-terminals belong to the excluded surface. Terminal
@@ -21424,6 +21533,12 @@ var node_pty_default = {
21424
21533
  open
21425
21534
  };
21426
21535
  //#endregion
21536
+ //#region src/node/external_packages/execa.ts
21537
+ /** Host package commands cannot install dependencies in the browser preview. */
21538
+ var execa_exports = /* @__PURE__ */ __exportAll({ execa: () => execa });
21539
+ /** Refuse external package commands in the worker host. */
21540
+ const execa = notImplementedFail("execa", "execa");
21541
+ //#endregion
21427
21542
  //#region src/node/external_packages/pi-ai.ts
21428
21543
  /**
21429
21544
  * `@earendil-works/pi-ai` stub, including its `/providers/all` and `/api/*.lazy`
@@ -21648,9 +21763,11 @@ const Server = WebSocketServer;
21648
21763
  const REPLACED_EXTERNAL_PACKAGES = [
21649
21764
  "@earendil-works/pi-ai",
21650
21765
  "@vscode/ripgrep",
21766
+ "@deepseek-ai/libreoffice-kit",
21651
21767
  "@deepseek-ai/node-addon-system/flock",
21652
21768
  "koffi",
21653
21769
  "node-pty",
21770
+ "execa",
21654
21771
  "sharp",
21655
21772
  "ws"
21656
21773
  ];
@@ -21685,10 +21802,10 @@ const BUILTINS = {
21685
21802
  buffer: () => buffer_exports,
21686
21803
  child_process: () => child_process_exports,
21687
21804
  crypto: () => crypto_exports,
21688
- "dns/promises": () => promises_exports$2,
21805
+ "dns/promises": () => promises_exports$3,
21689
21806
  events: () => events_exports,
21690
21807
  fs: () => fs_exports,
21691
- "fs/promises": () => promises_exports$1,
21808
+ "fs/promises": () => promises_exports$2,
21692
21809
  http: () => http_exports,
21693
21810
  module: () => module_exports,
21694
21811
  net: () => net_exports,
@@ -21698,6 +21815,7 @@ const BUILTINS = {
21698
21815
  perf_hooks: () => perf_hooks_exports,
21699
21816
  sqlite: () => sqlite_exports,
21700
21817
  stream: () => stream_exports,
21818
+ "stream/promises": () => promises_exports$1,
21701
21819
  "timers/promises": () => promises_exports,
21702
21820
  tty: () => tty_exports,
21703
21821
  url: () => url_exports,
@@ -21709,10 +21827,12 @@ const BUILTINS = {
21709
21827
  };
21710
21828
  /** Exact package or subpath specifiers served by worker stubs and fakes. */
21711
21829
  const EXTERNALS = {
21830
+ "@deepseek-ai/libreoffice-kit": () => libreoffice_kit_exports,
21712
21831
  "@deepseek-ai/node-addon-system/flock": () => node_addon_system_flock_exports,
21713
21832
  "koffi": () => koffi_exports,
21714
21833
  "sharp": () => sharp_exports,
21715
21834
  "node-pty": () => node_pty_exports,
21835
+ "execa": () => execa_exports,
21716
21836
  "ws": () => ws_exports,
21717
21837
  "@vscode/ripgrep": () => ripgrep_exports,
21718
21838
  "@earendil-works/pi-ai": () => pi_ai_exports
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-experimental-webworker-runtime",
3
3
  "description": "Browser-only harness runtime: in-memory VFS, module transform and loader, postMessage tunnel, and the dedicated Web Worker assembly, with the Node-compatibility layer that lets the host tree run unchanged",
4
- "version": "0.1.6-alpha.1",
4
+ "version": "0.1.7-alpha.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -34,35 +34,37 @@
34
34
  "buffer": "^6.0.3",
35
35
  "picomatch": "^4.0.4",
36
36
  "readable-stream": "^4.7.0",
37
- "@deepseek-ai/dsh-util-crypto": "^0.1.6-alpha.1"
37
+ "@deepseek-ai/dsh-client-web": "^0.1.7-alpha.1",
38
+ "@deepseek-ai/dsh-util-crypto": "^0.1.7-alpha.1"
38
39
  },
39
40
  "peerDependencies": {
40
- "@deepseek-ai/cordis-plugin-loader": "^1.0.3",
41
- "@deepseek-ai/dsh-client-modules": "^0.1.6-alpha.1",
42
- "@deepseek-ai/dsh-client-connection": "^0.1.6-alpha.1",
43
- "@deepseek-ai/dsh-host-webserver": "^0.1.6-alpha.1",
44
- "@deepseek-ai/cordis": "^4.0.2"
41
+ "@deepseek-ai/cordis": "^4.0.3",
42
+ "@deepseek-ai/cordis-plugin-loader": "^1.0.4",
43
+ "@deepseek-ai/dsh-client-connection": "^0.1.7-alpha.1",
44
+ "@deepseek-ai/dsh-host-webserver": "^0.1.7-alpha.1",
45
+ "@deepseek-ai/dsh-client-modules": "^0.1.7-alpha.1"
45
46
  },
46
47
  "devDependencies": {
47
48
  "@types/picomatch": "^3.0.2",
48
49
  "@types/readable-stream": "^4.0.24",
49
50
  "chokidar": "^5.0.0",
50
- "@deepseek-ai/cordis": "^4.0.2",
51
- "@deepseek-ai/cordis-plugin-loader": "^1.0.3",
52
- "@deepseek-ai/dsh-bash-sandbox": "^0.1.6-alpha.1",
53
- "@deepseek-ai/dsh-client-connection": "^0.1.6-alpha.1",
54
- "@deepseek-ai/dsh-api-gateway": "^0.1.6-alpha.1",
55
- "@deepseek-ai/dsh-client-file-upload": "^0.1.6-alpha.1",
56
- "@deepseek-ai/dsh-client-modules": "^0.1.6-alpha.1",
57
- "@deepseek-ai/dsh-host-webserver": "^0.1.6-alpha.1",
58
- "@deepseek-ai/dsh-sandbox-local": "^0.1.6-alpha.1",
59
- "@deepseek-ai/dsh-session": "^0.1.6-alpha.1",
60
- "@deepseek-ai/dsh-session-projection": "^0.1.6-alpha.1",
61
- "@deepseek-ai/dsh-sandbox-policy": "^0.1.6-alpha.1",
62
- "@deepseek-ai/dsh-session-persistence-jsonl": "^0.1.6-alpha.1",
63
- "@deepseek-ai/dsh-subagent": "^0.1.6-alpha.1",
64
- "@deepseek-ai/dsh-subprocess-local": "^0.1.6-alpha.1",
65
- "@deepseek-ai/node-addon-system": "^0.1.2"
51
+ "@deepseek-ai/cordis": "^4.0.3",
52
+ "@deepseek-ai/cordis-plugin-loader": "^1.0.4",
53
+ "@deepseek-ai/dsh-api-gateway": "^0.1.7-alpha.1",
54
+ "@deepseek-ai/dsh-app-boot": "^0.1.7-alpha.1",
55
+ "@deepseek-ai/dsh-bash-sandbox": "^0.1.7-alpha.1",
56
+ "@deepseek-ai/dsh-client-file-upload": "^0.1.7-alpha.1",
57
+ "@deepseek-ai/dsh-client-connection": "^0.1.7-alpha.1",
58
+ "@deepseek-ai/dsh-client-modules": "^0.1.7-alpha.1",
59
+ "@deepseek-ai/dsh-sandbox-local": "^0.1.7-alpha.1",
60
+ "@deepseek-ai/dsh-sandbox-policy": "^0.1.7-alpha.1",
61
+ "@deepseek-ai/dsh-session": "^0.1.7-alpha.1",
62
+ "@deepseek-ai/dsh-session-projection": "^0.1.7-alpha.1",
63
+ "@deepseek-ai/dsh-session-persistence-jsonl": "^0.1.7-alpha.1",
64
+ "@deepseek-ai/dsh-subagent": "^0.1.7-alpha.1",
65
+ "@deepseek-ai/dsh-subprocess-local": "^0.1.7-alpha.1",
66
+ "@deepseek-ai/node-addon-system": "^0.1.2",
67
+ "@deepseek-ai/dsh-host-webserver": "^0.1.7-alpha.1"
66
68
  },
67
69
  "files": [
68
70
  "lib/index.js",