@cloudflare/workspace 0.0.0-alpha.3 → 0.0.0-alpha.4
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/README.md +57 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +126 -20
- package/dist/index.js.map +1 -1
- package/dist/observe/cloudflare.d.ts +27 -0
- package/dist/observe/cloudflare.js +38 -0
- package/dist/observe/cloudflare.js.map +1 -0
- package/dist/shared-DYgflRlD.d.ts +63 -0
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -64,6 +64,63 @@ export default {
|
|
|
64
64
|
} satisfies ExportedHandler<Env>;
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
+
## Observability
|
|
68
|
+
|
|
69
|
+
The package emits one span per documented operation through an optional
|
|
70
|
+
observer hook. Pass an observer to the `Workspace` constructor:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import { Workspace, type WorkspaceObserver } from "@cloudflare/workspace";
|
|
74
|
+
|
|
75
|
+
const observer: WorkspaceObserver = {
|
|
76
|
+
async span(name, attributes, run) {
|
|
77
|
+
// Wrap `run` however your tracing backend wants. The Cloudflare
|
|
78
|
+
// runtime, OpenTelemetry, and a plain console.log adapter all fit
|
|
79
|
+
// the same shape.
|
|
80
|
+
return run({ setAttribute: () => {} });
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const ws = new Workspace({
|
|
85
|
+
storage: this.ctx.storage,
|
|
86
|
+
backends: [...],
|
|
87
|
+
observer,
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The observer's `span(name, attributes, run)` wraps each operation. It
|
|
92
|
+
starts a span, runs the callback, and ends the span when the callback
|
|
93
|
+
returns or its promise settles. Errors thrown by the work record
|
|
94
|
+
`error.name` and `error.message` and propagate.
|
|
95
|
+
|
|
96
|
+
The span names the package emits today:
|
|
97
|
+
|
|
98
|
+
- `workspace.connect` — one per `connect()` attempt against a single
|
|
99
|
+
backend. Tagged with `workspace.backend.id`.
|
|
100
|
+
- `workspace.sync.push` / `workspace.sync.pull` — one per sync call.
|
|
101
|
+
Tagged with the entry counts (`workspace.sync.pushed`,
|
|
102
|
+
`workspace.sync.applied`, `workspace.sync.skipped`).
|
|
103
|
+
- `workspace.shell.exec` — the full exec bracket from the
|
|
104
|
+
`WorkspaceStub`. Contains `workspace.sync.push`,
|
|
105
|
+
`workspace.shell.exec.spawn`, and `workspace.sync.pull` as nested
|
|
106
|
+
children. Tagged with `workspace.shell.exit_code`,
|
|
107
|
+
`workspace.shell.pushed`, `workspace.shell.pulled`, and
|
|
108
|
+
`workspace.shell.skipped`.
|
|
109
|
+
- `workspace.fs.<op>` — one per filesystem call routed through the
|
|
110
|
+
stub (`readFile`, `writeFile`, `stat`, `readdir`, `find`, `ls`,
|
|
111
|
+
`grep`, `mkdir`, `rm`). Tagged with `workspace.fs.path` and, where
|
|
112
|
+
meaningful, `workspace.fs.entries` or `workspace.fs.matches`.
|
|
113
|
+
|
|
114
|
+
Attribute values are restricted to `boolean | number | string` so the
|
|
115
|
+
same observer shape works against the Cloudflare runtime's built-in
|
|
116
|
+
`ctx.tracing.enterSpan(...)` API, OpenTelemetry, or a recording test
|
|
117
|
+
observer. Adapter packages for the Cloudflare runtime and for
|
|
118
|
+
OpenTelemetry are forthcoming.
|
|
119
|
+
|
|
120
|
+
The default is a no-op observer with no allocation or async overhead
|
|
121
|
+
beyond what the callback itself does, so the package has no
|
|
122
|
+
observability cost when callers do not opt in.
|
|
123
|
+
|
|
67
124
|
## Stub disposal
|
|
68
125
|
|
|
69
126
|
capnweb does not garbage-collect remote stubs. On the long-lived
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { _ as Database, a as SQLiteWorkspaceProviderOptions, c as WriteFileOptions, d as ReadFileOptions, f as WorkspaceDirentResult, g as WorkspaceFoundEntry, h as WorkspaceGrepMatch, i as SQLiteWorkspaceProvider, l as WorkspaceStatResult, m as GrepOptions, n as SkippedEntry, o as WorkspaceFilesystem, p as MkdirOptions, r as ChangeEntry, s as WriteFileContent, t as ApplyResult, u as RmOptions, v as DurableObjectStorageLike } from "./shared-RIdME5uo.js";
|
|
2
|
+
import { a as noopObserver, i as WorkspaceSpan, n as WorkspaceAttributes, r as WorkspaceObserver, t as WorkspaceAttributeValue } from "./shared-DYgflRlD.js";
|
|
2
3
|
import { RpcTarget } from "capnweb";
|
|
3
4
|
import { RpcTarget as RpcTarget$1, WorkerEntrypoint } from "cloudflare:workers";
|
|
4
5
|
|
|
@@ -261,7 +262,7 @@ interface Sync {
|
|
|
261
262
|
}
|
|
262
263
|
declare class WorkspaceShell {
|
|
263
264
|
#private;
|
|
264
|
-
constructor(shell: ShellRPC, sync: Sync);
|
|
265
|
+
constructor(shell: ShellRPC, sync: Sync, observer?: WorkspaceObserver);
|
|
265
266
|
exec(command: string): Promise<ExecHandle<undefined>>;
|
|
266
267
|
exec(command: string, options: ExecOptions<undefined>): Promise<ExecHandle<undefined>>;
|
|
267
268
|
exec(command: string, options: ExecOptions<"utf8">): Promise<ExecHandle<"utf8">>;
|
|
@@ -280,6 +281,7 @@ interface WorkspaceOptions {
|
|
|
280
281
|
now?: () => number;
|
|
281
282
|
sessionId?: string;
|
|
282
283
|
mounts?: Record<string, MountValue>;
|
|
284
|
+
observer?: WorkspaceObserver;
|
|
283
285
|
reconnect?: ReconnectOptions;
|
|
284
286
|
}
|
|
285
287
|
interface ReconnectOptions {
|
|
@@ -293,6 +295,7 @@ declare class Workspace {
|
|
|
293
295
|
ensureMountsIndexed(): Promise<void>;
|
|
294
296
|
mounts(): Map<string, Mount>;
|
|
295
297
|
get db(): Database;
|
|
298
|
+
get observer(): WorkspaceObserver;
|
|
296
299
|
get fs(): WorkspaceFilesystem;
|
|
297
300
|
/**
|
|
298
301
|
* Underlying dofs `SQLiteWorkspaceProvider` over the local store.
|
|
@@ -380,5 +383,5 @@ declare class WorkspaceStub extends RpcTarget {
|
|
|
380
383
|
get shell(): WorkspaceShellStub;
|
|
381
384
|
}
|
|
382
385
|
//#endregion
|
|
383
|
-
export { type ApplyResult, type BackendHandle, CloudflareContainerBackend, type CloudflareContainerBackendOptions, type DurableObjectStorageLike, type EagerMount, type ExecEncoding, type ExecHandle, type ExecOptions, type ExecResult, type GetExecOptions, type IWorkspaceContainerAPI, type KillSignal, type Mount, type MountBase, type MountContext, type MountFactory, type MountWriteAPI, R2Bucket, type R2BucketBinding, type R2BucketOptions, SQLiteWorkspaceProvider, type SQLiteWorkspaceProviderOptions, type SkippedEntry, TestBackend, type TestBackendOptions, Workspace, type WorkspaceBackend, WorkspaceContainerAPI, type WorkspaceExecEvent, WorkspaceExecHandleStub, type WorkspaceExecOptions, type WorkspaceExecResult, WorkspaceFilesystemStub, type WorkspaceOptions, WorkspaceProxy, type WorkspaceProxyProps, type WorkspaceRef, WorkspaceShell, WorkspaceShellStub, WorkspaceStub, withWorkspaceContainer };
|
|
386
|
+
export { type ApplyResult, type BackendHandle, CloudflareContainerBackend, type CloudflareContainerBackendOptions, type DurableObjectStorageLike, type EagerMount, type ExecEncoding, type ExecHandle, type ExecOptions, type ExecResult, type GetExecOptions, type IWorkspaceContainerAPI, type KillSignal, type Mount, type MountBase, type MountContext, type MountFactory, type MountWriteAPI, R2Bucket, type R2BucketBinding, type R2BucketOptions, SQLiteWorkspaceProvider, type SQLiteWorkspaceProviderOptions, type SkippedEntry, TestBackend, type TestBackendOptions, Workspace, type WorkspaceAttributeValue, type WorkspaceAttributes, type WorkspaceBackend, WorkspaceContainerAPI, type WorkspaceExecEvent, WorkspaceExecHandleStub, type WorkspaceExecOptions, type WorkspaceExecResult, WorkspaceFilesystemStub, type WorkspaceObserver, type WorkspaceOptions, WorkspaceProxy, type WorkspaceProxyProps, type WorkspaceRef, WorkspaceShell, WorkspaceShellStub, type WorkspaceSpan, WorkspaceStub, noopObserver, withWorkspaceContainer };
|
|
384
387
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -2035,6 +2035,63 @@ function R2Bucket(bucket, options = {}) {
|
|
|
2035
2035
|
};
|
|
2036
2036
|
}
|
|
2037
2037
|
//#endregion
|
|
2038
|
+
//#region src/observe.ts
|
|
2039
|
+
const NOOP_SPAN = { setAttribute() {} };
|
|
2040
|
+
/**
|
|
2041
|
+
* Observer that does no work. Used when the caller does not pass one.
|
|
2042
|
+
* Calling `span(...)` returns the callback's promise directly, with no
|
|
2043
|
+
* extra `await` and no allocation beyond what the callback itself does.
|
|
2044
|
+
*/
|
|
2045
|
+
const noopObserver = { span(_name, _attributes, run) {
|
|
2046
|
+
return run(NOOP_SPAN);
|
|
2047
|
+
} };
|
|
2048
|
+
/**
|
|
2049
|
+
* Internal helper: wraps `run` with `observer.span(...)`, applies any
|
|
2050
|
+
* `undefined`-filtered attributes the work produces on settlement, and
|
|
2051
|
+
* records error details on rejection before re-throwing.
|
|
2052
|
+
*
|
|
2053
|
+
* The `finalize` callback runs with the result (on success) or the
|
|
2054
|
+
* thrown error (on failure) and is the single place call sites attach
|
|
2055
|
+
* post-hoc attributes like byte counts, exit codes, or applied counts.
|
|
2056
|
+
* Both branches are wrapped in try/catch so a buggy `finalize` does
|
|
2057
|
+
* not mask the original outcome.
|
|
2058
|
+
*/
|
|
2059
|
+
function withSpan(observer, name, attributes, run, finalize) {
|
|
2060
|
+
return observer.span(name, attributes, async (span) => {
|
|
2061
|
+
try {
|
|
2062
|
+
const value = await run();
|
|
2063
|
+
if (finalize) try {
|
|
2064
|
+
finalize(span, {
|
|
2065
|
+
ok: true,
|
|
2066
|
+
value
|
|
2067
|
+
});
|
|
2068
|
+
} catch {}
|
|
2069
|
+
return value;
|
|
2070
|
+
} catch (error) {
|
|
2071
|
+
recordError(span, error);
|
|
2072
|
+
if (finalize) try {
|
|
2073
|
+
finalize(span, {
|
|
2074
|
+
ok: false,
|
|
2075
|
+
error
|
|
2076
|
+
});
|
|
2077
|
+
} catch {}
|
|
2078
|
+
throw error;
|
|
2079
|
+
}
|
|
2080
|
+
});
|
|
2081
|
+
}
|
|
2082
|
+
/**
|
|
2083
|
+
* Records `error.message` and `error.name` on `span`. Adapters that
|
|
2084
|
+
* want richer error reporting can subscribe to the underlying span
|
|
2085
|
+
* system directly; the workspace itself only forwards what the
|
|
2086
|
+
* Cloudflare `Span` surface accepts.
|
|
2087
|
+
*/
|
|
2088
|
+
function recordError(span, error) {
|
|
2089
|
+
if (error instanceof Error) {
|
|
2090
|
+
span.setAttribute("error.name", error.name);
|
|
2091
|
+
span.setAttribute("error.message", error.message);
|
|
2092
|
+
} else span.setAttribute("error.message", String(error));
|
|
2093
|
+
}
|
|
2094
|
+
//#endregion
|
|
2038
2095
|
//#region src/proxy.ts
|
|
2039
2096
|
var WorkspaceProxy = class extends WorkerEntrypoint {
|
|
2040
2097
|
async fetch(request) {
|
|
@@ -2054,20 +2111,28 @@ var WorkspaceProxy = class extends WorkerEntrypoint {
|
|
|
2054
2111
|
var WorkspaceShell = class {
|
|
2055
2112
|
#shell;
|
|
2056
2113
|
#sync;
|
|
2057
|
-
|
|
2114
|
+
#observer;
|
|
2115
|
+
constructor(shell, sync, observer = noopObserver) {
|
|
2058
2116
|
this.#shell = shell;
|
|
2059
2117
|
this.#sync = sync;
|
|
2118
|
+
this.#observer = observer;
|
|
2060
2119
|
}
|
|
2061
2120
|
async exec(command, options = {}) {
|
|
2062
2121
|
let pushed = 0;
|
|
2063
2122
|
try {
|
|
2064
2123
|
pushed = await this.#sync.push();
|
|
2065
2124
|
} catch {}
|
|
2066
|
-
const envelope = await this.#shell.exec
|
|
2125
|
+
const envelope = await withSpan(this.#observer, "workspace.shell.exec.spawn", {
|
|
2126
|
+
"workspace.shell.cwd": options.cwd,
|
|
2127
|
+
"workspace.shell.timeout_ms": options.timeoutMs,
|
|
2128
|
+
"workspace.shell.id": options.id
|
|
2129
|
+
}, () => this.#shell.exec({
|
|
2067
2130
|
command,
|
|
2068
2131
|
id: options.id,
|
|
2069
2132
|
cwd: options.cwd,
|
|
2070
2133
|
timeoutMs: options.timeoutMs
|
|
2134
|
+
}), (span, outcome) => {
|
|
2135
|
+
if (outcome.ok) span.setAttribute("workspace.shell.id", outcome.value.id);
|
|
2071
2136
|
});
|
|
2072
2137
|
const events = disposeOnDone$1(envelope.events, () => maybeDispose$1(envelope));
|
|
2073
2138
|
return wrapHandle(this.#shell, this.#sync, envelope.id, events, options.encoding, pushed);
|
|
@@ -2263,31 +2328,52 @@ var WorkspaceFilesystemStub = class extends RpcTarget {
|
|
|
2263
2328
|
untrackStub(this);
|
|
2264
2329
|
}
|
|
2265
2330
|
readFile(path, optionsOrEncoding) {
|
|
2266
|
-
return this.#ws.fs.readFile(path, optionsOrEncoding);
|
|
2331
|
+
return withSpan(this.#ws.observer, "workspace.fs.readFile", { "workspace.fs.path": path }, () => this.#ws.fs.readFile(path, optionsOrEncoding));
|
|
2267
2332
|
}
|
|
2268
2333
|
stat(path) {
|
|
2269
|
-
return this.#ws.fs.stat(path);
|
|
2334
|
+
return withSpan(this.#ws.observer, "workspace.fs.stat", { "workspace.fs.path": path }, () => this.#ws.fs.stat(path));
|
|
2270
2335
|
}
|
|
2271
2336
|
readdir(path) {
|
|
2272
|
-
return this.#ws.fs.readdir(path)
|
|
2337
|
+
return withSpan(this.#ws.observer, "workspace.fs.readdir", { "workspace.fs.path": path }, () => this.#ws.fs.readdir(path), (span, outcome) => {
|
|
2338
|
+
if (outcome.ok) span.setAttribute("workspace.fs.entries", outcome.value.length);
|
|
2339
|
+
});
|
|
2273
2340
|
}
|
|
2274
2341
|
find(directory, pattern) {
|
|
2275
|
-
return this.#ws.fs.find
|
|
2342
|
+
return withSpan(this.#ws.observer, "workspace.fs.find", {
|
|
2343
|
+
"workspace.fs.path": directory,
|
|
2344
|
+
"workspace.fs.pattern": pattern
|
|
2345
|
+
}, () => this.#ws.fs.find(directory, pattern), (span, outcome) => {
|
|
2346
|
+
if (outcome.ok) span.setAttribute("workspace.fs.matches", outcome.value.length);
|
|
2347
|
+
});
|
|
2276
2348
|
}
|
|
2277
2349
|
ls(prefix) {
|
|
2278
|
-
return this.#ws.fs.ls(prefix)
|
|
2350
|
+
return withSpan(this.#ws.observer, "workspace.fs.ls", { "workspace.fs.path": prefix }, () => this.#ws.fs.ls(prefix), (span, outcome) => {
|
|
2351
|
+
if (outcome.ok) span.setAttribute("workspace.fs.entries", outcome.value.length);
|
|
2352
|
+
});
|
|
2279
2353
|
}
|
|
2280
2354
|
grep(pattern, path, options = {}) {
|
|
2281
|
-
return this.#ws.fs.grep
|
|
2355
|
+
return withSpan(this.#ws.observer, "workspace.fs.grep", {
|
|
2356
|
+
"workspace.fs.path": path,
|
|
2357
|
+
"workspace.fs.pattern": pattern
|
|
2358
|
+
}, () => this.#ws.fs.grep(pattern, path, options), (span, outcome) => {
|
|
2359
|
+
if (outcome.ok) span.setAttribute("workspace.fs.matches", outcome.value.length);
|
|
2360
|
+
});
|
|
2282
2361
|
}
|
|
2283
2362
|
writeFile(path, content, options = {}) {
|
|
2284
|
-
return this.#ws.fs.writeFile(path, content, options);
|
|
2363
|
+
return withSpan(this.#ws.observer, "workspace.fs.writeFile", { "workspace.fs.path": path }, () => this.#ws.fs.writeFile(path, content, options));
|
|
2285
2364
|
}
|
|
2286
2365
|
mkdir(path, options = {}) {
|
|
2287
|
-
return this.#ws.fs.mkdir
|
|
2366
|
+
return withSpan(this.#ws.observer, "workspace.fs.mkdir", {
|
|
2367
|
+
"workspace.fs.path": path,
|
|
2368
|
+
"workspace.fs.recursive": options.recursive
|
|
2369
|
+
}, () => this.#ws.fs.mkdir(path, options));
|
|
2288
2370
|
}
|
|
2289
2371
|
rm(path, options = {}) {
|
|
2290
|
-
return this.#ws.fs.rm
|
|
2372
|
+
return withSpan(this.#ws.observer, "workspace.fs.rm", {
|
|
2373
|
+
"workspace.fs.path": path,
|
|
2374
|
+
"workspace.fs.recursive": options.recursive,
|
|
2375
|
+
"workspace.fs.force": options.force
|
|
2376
|
+
}, () => this.#ws.fs.rm(path, options));
|
|
2291
2377
|
}
|
|
2292
2378
|
};
|
|
2293
2379
|
var WorkspaceExecHandleStub = class extends RpcTarget {
|
|
@@ -2320,10 +2406,19 @@ var WorkspaceShellStub = class extends RpcTarget {
|
|
|
2320
2406
|
untrackStub(this);
|
|
2321
2407
|
}
|
|
2322
2408
|
async exec(command, options = {}) {
|
|
2323
|
-
return new WorkspaceExecHandleStub(
|
|
2409
|
+
return new WorkspaceExecHandleStub(withSpan(this.#ws.observer, "workspace.shell.exec", {
|
|
2410
|
+
"workspace.shell.cwd": options.cwd,
|
|
2411
|
+
"workspace.shell.encoding": options.encoding
|
|
2412
|
+
}, () => options.encoding === "utf8" ? this.#ws.shell.exec(command, {
|
|
2324
2413
|
cwd: options.cwd,
|
|
2325
2414
|
encoding: "utf8"
|
|
2326
|
-
}).then((handle) => handle.result()) : this.#ws.shell.exec(command, { cwd: options.cwd }).then((handle) => handle.result()))
|
|
2415
|
+
}).then((handle) => handle.result()) : this.#ws.shell.exec(command, { cwd: options.cwd }).then((handle) => handle.result()), (span, outcome) => {
|
|
2416
|
+
if (!outcome.ok) return;
|
|
2417
|
+
span.setAttribute("workspace.shell.exit_code", outcome.value.exitCode);
|
|
2418
|
+
span.setAttribute("workspace.shell.pushed", outcome.value.pushed);
|
|
2419
|
+
span.setAttribute("workspace.shell.pulled", outcome.value.pulled);
|
|
2420
|
+
span.setAttribute("workspace.shell.skipped", outcome.value.skipped.length);
|
|
2421
|
+
}));
|
|
2327
2422
|
}
|
|
2328
2423
|
};
|
|
2329
2424
|
var WorkspaceStub = class extends RpcTarget {
|
|
@@ -2736,6 +2831,7 @@ var Workspace = class {
|
|
|
2736
2831
|
#provider;
|
|
2737
2832
|
#backends;
|
|
2738
2833
|
#reconnect;
|
|
2834
|
+
#observer;
|
|
2739
2835
|
#now;
|
|
2740
2836
|
#mounts;
|
|
2741
2837
|
#mountIndex;
|
|
@@ -2755,6 +2851,7 @@ var Workspace = class {
|
|
|
2755
2851
|
initialDelayMs: 0,
|
|
2756
2852
|
maxDelayMs: 0
|
|
2757
2853
|
};
|
|
2854
|
+
this.#observer = options.observer ?? noopObserver;
|
|
2758
2855
|
this.#mounts = buildMountRegistry(options.mounts, {
|
|
2759
2856
|
sessionId: options.sessionId,
|
|
2760
2857
|
vfs: () => this.provider()
|
|
@@ -2774,6 +2871,9 @@ var Workspace = class {
|
|
|
2774
2871
|
get db() {
|
|
2775
2872
|
return this.#db;
|
|
2776
2873
|
}
|
|
2874
|
+
get observer() {
|
|
2875
|
+
return this.#observer;
|
|
2876
|
+
}
|
|
2777
2877
|
get fs() {
|
|
2778
2878
|
return this.#fs;
|
|
2779
2879
|
}
|
|
@@ -2825,18 +2925,24 @@ var Workspace = class {
|
|
|
2825
2925
|
return new WorkspaceStub(this);
|
|
2826
2926
|
}
|
|
2827
2927
|
push() {
|
|
2828
|
-
return this.#serialize(async () => {
|
|
2928
|
+
return this.#serialize(() => withSpan(this.#observer, "workspace.sync.push", {}, async () => {
|
|
2829
2929
|
await this.ready();
|
|
2830
2930
|
if (!this.#handle) throw new Error("Workspace not connected");
|
|
2831
2931
|
return pushOnce(this.#db, this.#handle.rpc.sync);
|
|
2832
|
-
})
|
|
2932
|
+
}, (span, outcome) => {
|
|
2933
|
+
if (outcome.ok) span.setAttribute("workspace.sync.pushed", outcome.value);
|
|
2934
|
+
}));
|
|
2833
2935
|
}
|
|
2834
2936
|
pull() {
|
|
2835
|
-
return this.#serialize(async () => {
|
|
2937
|
+
return this.#serialize(() => withSpan(this.#observer, "workspace.sync.pull", {}, async () => {
|
|
2836
2938
|
await this.ready();
|
|
2837
2939
|
if (!this.#handle) throw new Error("Workspace not connected");
|
|
2838
2940
|
return pullOnce(this.#db, this.#handle.rpc.sync);
|
|
2839
|
-
})
|
|
2941
|
+
}, (span, outcome) => {
|
|
2942
|
+
if (!outcome.ok) return;
|
|
2943
|
+
span.setAttribute("workspace.sync.applied", outcome.value.applied);
|
|
2944
|
+
span.setAttribute("workspace.sync.skipped", outcome.value.skipped.length);
|
|
2945
|
+
}));
|
|
2840
2946
|
}
|
|
2841
2947
|
#serialize(fn) {
|
|
2842
2948
|
const run = this.#mutationTail.then(fn, fn);
|
|
@@ -2870,10 +2976,10 @@ var Workspace = class {
|
|
|
2870
2976
|
async #connectOnce() {
|
|
2871
2977
|
const errors = [];
|
|
2872
2978
|
for (const backend of this.#backends) try {
|
|
2873
|
-
const handle = await backend.connect();
|
|
2979
|
+
const handle = await withSpan(this.#observer, "workspace.connect", { "workspace.backend.id": backend.id }, () => backend.connect());
|
|
2874
2980
|
await reconcileWatermarks(this.#db, handle.rpc.sync);
|
|
2875
2981
|
this.#handle = handle;
|
|
2876
|
-
this.#shell = new WorkspaceShell(handle.rpc.shell, this);
|
|
2982
|
+
this.#shell = new WorkspaceShell(handle.rpc.shell, this, this.#observer);
|
|
2877
2983
|
if (handle.closed) handle.closed.catch(() => {}).then(() => {
|
|
2878
2984
|
if (this.#handle === handle) {
|
|
2879
2985
|
this.#handle = void 0;
|
|
@@ -2897,6 +3003,6 @@ function sleep(ms) {
|
|
|
2897
3003
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
2898
3004
|
}
|
|
2899
3005
|
//#endregion
|
|
2900
|
-
export { CloudflareContainerBackend, R2Bucket, SQLiteWorkspaceProvider, TestBackend, Workspace, WorkspaceContainerAPI, WorkspaceExecHandleStub, WorkspaceFilesystemStub, WorkspaceProxy, WorkspaceShell, WorkspaceShellStub, WorkspaceStub, withWorkspaceContainer };
|
|
3006
|
+
export { CloudflareContainerBackend, R2Bucket, SQLiteWorkspaceProvider, TestBackend, Workspace, WorkspaceContainerAPI, WorkspaceExecHandleStub, WorkspaceFilesystemStub, WorkspaceProxy, WorkspaceShell, WorkspaceShellStub, WorkspaceStub, noopObserver, withWorkspaceContainer };
|
|
2901
3007
|
|
|
2902
3008
|
//# sourceMappingURL=index.js.map
|