@dxos/cli-util 0.0.0 → 0.8.4-main.03d5cd7b56

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 (49) hide show
  1. package/dist/lib/node-esm/chunk-N5LOOWPE.mjs +27 -0
  2. package/dist/lib/node-esm/chunk-N5LOOWPE.mjs.map +7 -0
  3. package/dist/lib/node-esm/index.mjs +554 -0
  4. package/dist/lib/node-esm/index.mjs.map +7 -0
  5. package/dist/lib/node-esm/meta.json +1 -0
  6. package/dist/lib/node-esm/testing/index.mjs +82 -0
  7. package/dist/lib/node-esm/testing/index.mjs.map +7 -0
  8. package/dist/types/src/index.d.ts +3 -0
  9. package/dist/types/src/index.d.ts.map +1 -0
  10. package/dist/types/src/services/command-config.d.ts +16 -0
  11. package/dist/types/src/services/command-config.d.ts.map +1 -0
  12. package/dist/types/src/services/index.d.ts +2 -0
  13. package/dist/types/src/services/index.d.ts.map +1 -0
  14. package/dist/types/src/testing/index.d.ts +3 -0
  15. package/dist/types/src/testing/index.d.ts.map +1 -0
  16. package/dist/types/src/testing/test-console.d.ts +37 -0
  17. package/dist/types/src/testing/test-console.d.ts.map +1 -0
  18. package/dist/types/src/testing/test-layer.d.ts +6 -0
  19. package/dist/types/src/testing/test-layer.d.ts.map +1 -0
  20. package/dist/types/src/util/form-builder.d.ts +56 -0
  21. package/dist/types/src/util/form-builder.d.ts.map +1 -0
  22. package/dist/types/src/util/form-builder.test.d.ts +2 -0
  23. package/dist/types/src/util/form-builder.test.d.ts.map +1 -0
  24. package/dist/types/src/util/index.d.ts +9 -0
  25. package/dist/types/src/util/index.d.ts.map +1 -0
  26. package/dist/types/src/util/options.d.ts +7 -0
  27. package/dist/types/src/util/options.d.ts.map +1 -0
  28. package/dist/types/src/util/platform.d.ts +12 -0
  29. package/dist/types/src/util/platform.d.ts.map +1 -0
  30. package/dist/types/src/util/printer.d.ts +10 -0
  31. package/dist/types/src/util/printer.d.ts.map +1 -0
  32. package/dist/types/src/util/runtime.d.ts +6 -0
  33. package/dist/types/src/util/runtime.d.ts.map +1 -0
  34. package/dist/types/src/util/space-format.d.ts +42 -0
  35. package/dist/types/src/util/space-format.d.ts.map +1 -0
  36. package/dist/types/src/util/space.d.ts +45 -0
  37. package/dist/types/src/util/space.d.ts.map +1 -0
  38. package/dist/types/src/util/timeout.d.ts +5 -0
  39. package/dist/types/src/util/timeout.d.ts.map +1 -0
  40. package/dist/types/tsconfig.tsbuildinfo +1 -0
  41. package/package.json +21 -15
  42. package/src/testing/test-console.ts +1 -2
  43. package/src/testing/test-layer.ts +0 -1
  44. package/src/util/form-builder.ts +1 -1
  45. package/src/util/platform.ts +1 -2
  46. package/src/util/printer.ts +1 -1
  47. package/src/util/runtime.ts +2 -4
  48. package/src/util/space-format.ts +86 -12
  49. package/src/util/space.ts +43 -29
@@ -0,0 +1,27 @@
1
+ import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
+ var __defProp = Object.defineProperty;
3
+ var __export = (target, all) => {
4
+ for (var name in all)
5
+ __defProp(target, name, { get: all[name], enumerable: true });
6
+ };
7
+
8
+ // src/services/command-config.ts
9
+ import * as Context from "effect/Context";
10
+ import * as Effect from "effect/Effect";
11
+ import * as Layer from "effect/Layer";
12
+ var CommandConfig = class _CommandConfig extends Context.Tag("CommandConfig")() {
13
+ static isJson = _CommandConfig.pipe(Effect.map((config) => config.json));
14
+ static isVerbose = _CommandConfig.pipe(Effect.map((config) => config.verbose));
15
+ static layerTest = Layer.succeed(_CommandConfig, {
16
+ json: true,
17
+ verbose: false,
18
+ profile: "default",
19
+ logLevel: "info"
20
+ });
21
+ };
22
+
23
+ export {
24
+ __export,
25
+ CommandConfig
26
+ };
27
+ //# sourceMappingURL=chunk-N5LOOWPE.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/services/command-config.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Context from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\n\nexport class CommandConfig extends Context.Tag('CommandConfig')<\n CommandConfig,\n {\n json: boolean;\n verbose: boolean;\n profile: string;\n logLevel: string;\n }\n>() {\n static isJson: Effect.Effect<boolean, never, CommandConfig> = CommandConfig.pipe(Effect.map((config) => config.json));\n static isVerbose: Effect.Effect<boolean, never, CommandConfig> = CommandConfig.pipe(\n Effect.map((config) => config.verbose),\n );\n\n static layerTest = Layer.succeed(CommandConfig, {\n json: true,\n verbose: false,\n profile: 'default',\n logLevel: 'info',\n });\n}\n"],
5
+ "mappings": ";;;;;;;;AAIA,YAAYA,aAAa;AACzB,YAAYC,YAAY;AACxB,YAAYC,WAAW;AAEhB,IAAMC,gBAAN,MAAMA,uBAA8BC,YAAI,eAAA,EAAA,EAAA;EAS7C,OAAOC,SAAuDF,eAAcG,KAAYC,WAAI,CAACC,WAAWA,OAAOC,IAAI,CAAA;EACnH,OAAOC,YAA0DP,eAAcG,KACtEC,WAAI,CAACC,WAAWA,OAAOG,OAAO,CAAA;EAGvC,OAAOC,YAAkBC,cAAQV,gBAAe;IAC9CM,MAAM;IACNE,SAAS;IACTG,SAAS;IACTC,UAAU;EACZ,CAAA;AACF;",
6
+ "names": ["Context", "Effect", "Layer", "CommandConfig", "Tag", "isJson", "pipe", "map", "config", "json", "isVerbose", "verbose", "layerTest", "succeed", "profile", "logLevel"]
7
+ }
@@ -0,0 +1,554 @@
1
+ import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
+ import {
3
+ CommandConfig,
4
+ __export
5
+ } from "./chunk-N5LOOWPE.mjs";
6
+
7
+ // src/util/form-builder.ts
8
+ var form_builder_exports = {};
9
+ __export(form_builder_exports, {
10
+ build: () => build,
11
+ each: () => each,
12
+ make: () => make,
13
+ nest: () => nest,
14
+ nestedOption: () => nestedOption,
15
+ option: () => option,
16
+ set: () => set,
17
+ when: () => when
18
+ });
19
+ import * as Ansi from "@effect/printer-ansi/Ansi";
20
+ import * as Doc from "@effect/printer/Doc";
21
+ import * as Option from "effect/Option";
22
+ import * as Pipeable from "effect/Pipeable";
23
+ var FormBuilderImpl = class {
24
+ entries = [];
25
+ title;
26
+ prefix;
27
+ constructor(options = {}) {
28
+ this.title = options.title;
29
+ this.prefix = options.prefix ?? "- ";
30
+ }
31
+ pipe() {
32
+ return Pipeable.pipeArguments(this, arguments);
33
+ }
34
+ };
35
+ var make = (props) => new FormBuilderImpl(props);
36
+ var calculateDimensions = (entries, prefix) => {
37
+ const maxKeyLen = Math.max(0, ...entries.map((entry) => entry.key.length));
38
+ const targetWidth = prefix.length + maxKeyLen + 2;
39
+ return {
40
+ maxKeyLen,
41
+ targetWidth
42
+ };
43
+ };
44
+ var buildKeyLine = (prefix, key, targetWidth) => {
45
+ return Doc.annotate(Doc.fill(targetWidth)(Doc.text(prefix + key + ": ")), Ansi.blackBright);
46
+ };
47
+ var setImpl = (builder, key, value, color) => {
48
+ if (value !== void 0) {
49
+ let valueDoc;
50
+ if (typeof value === "object" && value !== null) {
51
+ valueDoc = value;
52
+ } else {
53
+ valueDoc = Doc.text(String(value));
54
+ }
55
+ if (color) {
56
+ const ansi = typeof color === "function" ? color(value) : color;
57
+ valueDoc = Doc.annotate(valueDoc, ansi);
58
+ }
59
+ builder.entries.push({
60
+ key,
61
+ value: valueDoc,
62
+ isNested: false
63
+ });
64
+ }
65
+ return builder;
66
+ };
67
+ function set(builderOrKey, keyOrValue, valueOrColor, color) {
68
+ if (builderOrKey instanceof FormBuilderImpl) {
69
+ const builder = builderOrKey;
70
+ const key = keyOrValue;
71
+ const value = valueOrColor;
72
+ return setImpl(builder, key, value, color);
73
+ } else {
74
+ const key = builderOrKey;
75
+ const value = keyOrValue;
76
+ const color2 = valueOrColor;
77
+ return (builder) => setImpl(builder, key, value, color2);
78
+ }
79
+ }
80
+ var nestImpl = (parent, key, builder) => {
81
+ const nestedBuilder = {
82
+ ...builder,
83
+ title: void 0,
84
+ entries: builder.entries
85
+ };
86
+ let valueDoc = build(nestedBuilder);
87
+ valueDoc = Doc.indent(valueDoc, 2);
88
+ parent.entries.push({
89
+ key,
90
+ value: valueDoc,
91
+ isNested: true
92
+ });
93
+ return parent;
94
+ };
95
+ function nest(parentOrKey, keyOrBuilder, builder) {
96
+ if (parentOrKey instanceof FormBuilderImpl) {
97
+ const parent = parentOrKey;
98
+ const key = keyOrBuilder;
99
+ return nestImpl(parent, key, builder);
100
+ } else {
101
+ const key = parentOrKey;
102
+ const builder2 = keyOrBuilder;
103
+ return (parent) => nestImpl(parent, key, builder2);
104
+ }
105
+ }
106
+ var optionImpl = (builder, key, value, color) => {
107
+ if (Option.isSome(value)) {
108
+ return setImpl(builder, key, value.value, color);
109
+ }
110
+ return builder;
111
+ };
112
+ function option(builderOrKey, keyOrValue, valueOrColor, color) {
113
+ if (builderOrKey instanceof FormBuilderImpl) {
114
+ const builder = builderOrKey;
115
+ const key = keyOrValue;
116
+ const value = valueOrColor;
117
+ return optionImpl(builder, key, value, color);
118
+ } else {
119
+ const key = builderOrKey;
120
+ const value = keyOrValue;
121
+ const color2 = valueOrColor;
122
+ return (builder) => optionImpl(builder, key, value, color2);
123
+ }
124
+ }
125
+ var nestedOptionImpl = (builder, key, value) => {
126
+ if (Option.isSome(value)) {
127
+ return nestImpl(builder, key, value.value);
128
+ }
129
+ return builder;
130
+ };
131
+ function nestedOption(builderOrKey, keyOrValue, value) {
132
+ if (builderOrKey instanceof FormBuilderImpl) {
133
+ const builder = builderOrKey;
134
+ const key = keyOrValue;
135
+ return nestedOptionImpl(builder, key, value);
136
+ } else {
137
+ const key = builderOrKey;
138
+ const value2 = keyOrValue;
139
+ return (builder) => nestedOptionImpl(builder, key, value2);
140
+ }
141
+ }
142
+ var whenImpl = (builder, condition, ...ops) => {
143
+ if (condition) {
144
+ for (const op of ops) {
145
+ op(builder);
146
+ }
147
+ }
148
+ return builder;
149
+ };
150
+ function when(builderOrCondition, conditionOrOp, ...ops) {
151
+ if (builderOrCondition instanceof FormBuilderImpl) {
152
+ const builder = builderOrCondition;
153
+ const condition = conditionOrOp;
154
+ return whenImpl(builder, condition, ...ops);
155
+ } else {
156
+ const condition = builderOrCondition;
157
+ const allOps = [
158
+ conditionOrOp,
159
+ ...ops
160
+ ].filter((op) => typeof op === "function");
161
+ return (builder) => whenImpl(builder, condition, ...allOps);
162
+ }
163
+ }
164
+ var eachImpl = (builder, items, fn3) => {
165
+ items.forEach((item) => fn3(item)(builder));
166
+ return builder;
167
+ };
168
+ function each(builderOrItems, itemsOrFn, fn3) {
169
+ if (builderOrItems instanceof FormBuilderImpl) {
170
+ const builder = builderOrItems;
171
+ const items = itemsOrFn;
172
+ return eachImpl(builder, items, fn3);
173
+ } else {
174
+ const items = builderOrItems;
175
+ const fn4 = itemsOrFn;
176
+ return (builder) => eachImpl(builder, items, fn4);
177
+ }
178
+ }
179
+ var build = (builder) => {
180
+ const { targetWidth } = calculateDimensions(builder.entries, builder.prefix);
181
+ const entryLines = [];
182
+ builder.entries.forEach(({ key, value, isNested }) => {
183
+ const keyLine = buildKeyLine(builder.prefix, key, targetWidth);
184
+ if (isNested) {
185
+ entryLines.push(Doc.hcat([
186
+ keyLine,
187
+ Doc.hardLine,
188
+ value
189
+ ]));
190
+ } else {
191
+ entryLines.push(Doc.hcat([
192
+ keyLine,
193
+ value
194
+ ]));
195
+ }
196
+ });
197
+ const entriesDoc = Doc.vsep(entryLines);
198
+ if (builder.title) {
199
+ const titleDoc = Doc.hcat([
200
+ Doc.annotate(Doc.text(builder.title), Ansi.combine(Ansi.bold, Ansi.cyan))
201
+ ]);
202
+ return Doc.cat(titleDoc, Doc.cat(Doc.line, entriesDoc));
203
+ }
204
+ return entriesDoc;
205
+ };
206
+
207
+ // src/util/options.ts
208
+ import * as Options from "@effect/cli/Options";
209
+ import { Key } from "@dxos/echo";
210
+ var Common = {
211
+ functionId: Options.text("function-id").pipe(Options.withDescription("EDGE Function ID.")),
212
+ spaceId: Options.text("space-id").pipe(Options.withSchema(Key.SpaceId), Options.withDescription("Space ID."))
213
+ };
214
+
215
+ // src/util/platform.ts
216
+ import * as Effect from "effect/Effect";
217
+ import { spawn } from "node:child_process";
218
+ var copyToClipboard = (text3) => Effect.tryPromise({
219
+ try: () => {
220
+ return new Promise((resolve, reject) => {
221
+ const platform = process.platform;
222
+ let command;
223
+ let args;
224
+ if (platform === "darwin") {
225
+ command = "pbcopy";
226
+ args = [];
227
+ } else if (platform === "win32") {
228
+ command = "clip";
229
+ args = [];
230
+ } else {
231
+ command = "xclip";
232
+ args = [
233
+ "-selection",
234
+ "clipboard"
235
+ ];
236
+ }
237
+ const proc = spawn(command, args);
238
+ proc.stdin?.write(text3);
239
+ proc.stdin?.end();
240
+ proc.on("close", (code) => {
241
+ if (code === 0) {
242
+ resolve();
243
+ } else {
244
+ if (platform === "linux") {
245
+ const proc2 = spawn("xsel", [
246
+ "--clipboard",
247
+ "--input"
248
+ ]);
249
+ proc2.stdin?.write(text3);
250
+ proc2.stdin?.end();
251
+ proc2.on("close", (code2) => {
252
+ if (code2 === 0) {
253
+ resolve();
254
+ } else {
255
+ reject(new Error("Failed to copy to clipboard"));
256
+ }
257
+ });
258
+ proc2.on("error", reject);
259
+ } else {
260
+ reject(new Error("Failed to copy to clipboard"));
261
+ }
262
+ }
263
+ });
264
+ proc.on("error", reject);
265
+ });
266
+ },
267
+ catch: (error) => new Error(`Failed to copy to clipboard: ${error}`)
268
+ });
269
+ var openBrowser = (url) => Effect.tryPromise({
270
+ try: () => {
271
+ return new Promise((resolve, reject) => {
272
+ const platform = process.platform;
273
+ let command;
274
+ let args;
275
+ if (platform === "darwin") {
276
+ command = "open";
277
+ args = [
278
+ url
279
+ ];
280
+ } else if (platform === "win32") {
281
+ command = "start";
282
+ args = [
283
+ url
284
+ ];
285
+ } else {
286
+ command = "xdg-open";
287
+ args = [
288
+ url
289
+ ];
290
+ }
291
+ const proc = spawn(command, args);
292
+ proc.on("close", (code) => {
293
+ if (code === 0) {
294
+ resolve();
295
+ } else {
296
+ reject(new Error("Failed to open browser"));
297
+ }
298
+ });
299
+ proc.on("error", reject);
300
+ });
301
+ },
302
+ catch: (error) => new Error(`Failed to open browser: ${error}`)
303
+ });
304
+
305
+ // src/util/printer.ts
306
+ import * as AnsiDoc from "@effect/printer-ansi/AnsiDoc";
307
+ import * as Doc2 from "@effect/printer/Doc";
308
+ var print = (doc) => AnsiDoc.render(doc, {
309
+ style: "pretty"
310
+ });
311
+ var printList = (items) => AnsiDoc.render(Doc2.vsep(items.map((item) => Doc2.cat(item, Doc2.hardLine))), {
312
+ style: "pretty"
313
+ });
314
+
315
+ // src/util/runtime.ts
316
+ import * as Effect2 from "effect/Effect";
317
+ import { ClientService } from "@dxos/client";
318
+ var withTypes = (...types) => Effect2.gen(function* () {
319
+ const client = yield* ClientService;
320
+ yield* Effect2.promise(() => client.addTypes(types));
321
+ });
322
+
323
+ // src/util/space.ts
324
+ import * as Console from "effect/Console";
325
+ import * as Effect3 from "effect/Effect";
326
+ import * as Layer from "effect/Layer";
327
+ import * as Option2 from "effect/Option";
328
+ import { getPersonalSpace } from "@dxos/app-toolkit";
329
+ import { ClientService as ClientService2 } from "@dxos/client";
330
+ import { Database } from "@dxos/echo";
331
+ import { BaseError } from "@dxos/errors";
332
+ import { QueueService } from "@dxos/functions";
333
+ import { log as log2 } from "@dxos/log";
334
+ import { EdgeReplicationSetting } from "@dxos/protocols/proto/dxos/echo/metadata";
335
+ import { isBun } from "@dxos/util";
336
+ var __dxlog_file = "/__w/dxos/dxos/packages/devtools/cli-util/src/util/space.ts";
337
+ var getSpace = (spaceId) => Effect3.gen(function* () {
338
+ const client = yield* ClientService2;
339
+ return yield* Option2.fromNullable(client.spaces.get(spaceId));
340
+ }).pipe(Effect3.catchTag("NoSuchElementException", () => Effect3.fail(new SpaceNotFoundError(spaceId))));
341
+ var spaceIdWithDefault = (spaceId) => Effect3.gen(function* () {
342
+ const client = yield* ClientService2;
343
+ return Option2.getOrElse(spaceId, () => {
344
+ const personal = getPersonalSpace(client);
345
+ if (!personal) {
346
+ throw new Error("No space ID provided and no personal space found.");
347
+ }
348
+ return personal.id;
349
+ });
350
+ });
351
+ var spaceLayer = (spaceId$, fallbackToPersonalSpace = false) => {
352
+ const getSpace2 = Effect3.fn(function* () {
353
+ const client = yield* ClientService2;
354
+ const resolveSpace = () => {
355
+ if (!fallbackToPersonalSpace) {
356
+ return spaceId$.pipe(Option2.flatMap((id) => Option2.fromNullable(client.spaces.get(id))));
357
+ }
358
+ return spaceId$.pipe(Option2.flatMap((id) => Option2.fromNullable(client.spaces.get(id))), Option2.orElse(() => Option2.fromNullable(getPersonalSpace(client))), Option2.orElse(() => Option2.fromNullable(client.spaces.get()[0])));
359
+ };
360
+ const space = resolveSpace().pipe(Option2.getOrUndefined);
361
+ if (space) {
362
+ yield* Effect3.promise(() => space.waitUntilReady());
363
+ }
364
+ return space;
365
+ });
366
+ const NO_DB_STUB = {
367
+ get db() {
368
+ throw new Error("Space not found");
369
+ }
370
+ };
371
+ const db = Layer.scoped(Database.Service, Effect3.acquireRelease(Effect3.gen(function* () {
372
+ const space = yield* getSpace2();
373
+ if (!space) {
374
+ return NO_DB_STUB;
375
+ }
376
+ return {
377
+ db: space.db
378
+ };
379
+ }), (holder) => holder === NO_DB_STUB ? Effect3.void : Effect3.promise(() => holder.db.flush())));
380
+ const queue = Layer.effect(QueueService, Effect3.gen(function* () {
381
+ const space = yield* getSpace2();
382
+ if (!space) {
383
+ return {
384
+ queues: {
385
+ get: (_dxn) => {
386
+ throw new Error("Queues not available");
387
+ },
388
+ create: () => {
389
+ throw new Error("Queues not available");
390
+ }
391
+ },
392
+ queue: void 0
393
+ };
394
+ }
395
+ return {
396
+ queues: space.queues,
397
+ queue: void 0
398
+ };
399
+ }));
400
+ return Layer.merge(db, queue);
401
+ };
402
+ var waitForSync = Effect3.fn(function* (space) {
403
+ if (!isBun()) {
404
+ return;
405
+ }
406
+ if (space.internal.data.edgeReplication !== EdgeReplicationSetting.ENABLED) {
407
+ yield* Console.log("Edge replication is disabled, enabling...");
408
+ yield* Effect3.promise(() => space.internal.setEdgeReplicationPreference(EdgeReplicationSetting.ENABLED));
409
+ }
410
+ yield* Effect3.promise(() => space.internal.syncToEdge({
411
+ onProgress: (state) => log2.info("syncing", {
412
+ state: state ?? "no connection to edge"
413
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 107, S: this })
414
+ }));
415
+ yield* Console.log("Sync complete");
416
+ });
417
+ var flushAndSync = Effect3.fn(function* (opts) {
418
+ yield* Database.flush(opts);
419
+ const spaceId = yield* Database.spaceId;
420
+ const space = yield* getSpace(spaceId);
421
+ yield* waitForSync(space);
422
+ });
423
+ var SpaceNotFoundError = class extends BaseError.extend("SpaceNotFoundError", "Space not found") {
424
+ constructor(spaceId, options) {
425
+ super({
426
+ context: {
427
+ spaceId
428
+ },
429
+ ...options
430
+ });
431
+ }
432
+ };
433
+
434
+ // src/util/space-format.ts
435
+ import * as Duration from "effect/Duration";
436
+ import * as Effect4 from "effect/Effect";
437
+ import { SpaceState } from "@dxos/client/echo";
438
+ var DEFAULT_OPTIONS = {
439
+ verbose: false,
440
+ truncateKeys: false,
441
+ waitSeconds: 0
442
+ };
443
+ var READ_TIMEOUT_SECONDS = 2;
444
+ var tryWithFallback = (label, run, fallback) => Effect4.tryPromise(run).pipe(Effect4.timeoutFail({
445
+ duration: Duration.seconds(READ_TIMEOUT_SECONDS),
446
+ onTimeout: () => new Error(`${label} timed out`)
447
+ }), Effect4.catchAll(() => Effect4.succeed(fallback)));
448
+ var tryWithFallbackSync = (read, fallback) => {
449
+ try {
450
+ return read();
451
+ } catch {
452
+ return fallback;
453
+ }
454
+ };
455
+ var formatSpace = Effect4.fn(function* (space, options = {}) {
456
+ const { waitSeconds } = {
457
+ ...DEFAULT_OPTIONS,
458
+ ...options
459
+ };
460
+ if (waitSeconds > 0) {
461
+ yield* Effect4.tryPromise(() => space.waitUntilReady()).pipe(Effect4.timeoutFail({
462
+ duration: Duration.seconds(waitSeconds),
463
+ onTimeout: () => new Error("waitUntilReady timed out")
464
+ }), Effect4.catchAll(() => Effect4.void));
465
+ }
466
+ const state = tryWithFallbackSync(() => space.state.get(), SpaceState.SPACE_INITIALIZING);
467
+ const ready = state === SpaceState.SPACE_READY;
468
+ const metrics = tryWithFallbackSync(() => space.internal.data.metrics, void 0);
469
+ const startup = metrics?.open && metrics?.ready ? metrics.ready.getTime() - metrics.open.getTime() : void 0;
470
+ const pipeline = tryWithFallbackSync(() => space.internal.data.pipeline, void 0);
471
+ const epoch = pipeline?.currentEpoch?.subject.assertion.number;
472
+ const syncStateRaw = yield* tryWithFallback("getSyncState", () => space.internal.db.coreDatabase.getSyncState(), {
473
+ peers: {}
474
+ });
475
+ const syncState = aggregateSyncState(syncStateRaw);
476
+ const name = ready ? tryWithFallbackSync(() => space.properties.name, void 0) : "loading...";
477
+ const members = tryWithFallbackSync(() => space.members.get().length, 0);
478
+ const objects = tryWithFallbackSync(() => space.internal.db.coreDatabase.getAllObjectIds().length, 0);
479
+ const key = options.truncateKeys ? tryWithFallbackSync(() => space.key.truncate(), "") : tryWithFallbackSync(() => space.key.toHex(), "");
480
+ return {
481
+ id: space.id,
482
+ state: SpaceState[state],
483
+ name,
484
+ members,
485
+ objects,
486
+ key,
487
+ epoch,
488
+ startup,
489
+ automergeRoot: pipeline?.spaceRootUrl,
490
+ // appliedEpoch,
491
+ syncState: `${syncState.count} ${getSyncIndicator(syncState.up, syncState.down)} (${syncState.peers} peers)`
492
+ };
493
+ });
494
+ var aggregateSyncState = (syncState) => {
495
+ const peers = Object.keys(syncState.peers ?? {}).length;
496
+ const missingOnLocal = Math.max(...Object.values(syncState.peers ?? {}).map((peer) => peer.missingOnLocal), 0);
497
+ const missingOnRemote = Math.max(...Object.values(syncState.peers ?? {}).map((peer) => peer.missingOnRemote), 0);
498
+ const differentDocuments = Math.max(...Object.values(syncState.peers ?? {}).map((peer) => peer.differentDocuments), 0);
499
+ return {
500
+ count: missingOnLocal + missingOnRemote + differentDocuments,
501
+ peers,
502
+ up: missingOnRemote > 0 || differentDocuments > 0,
503
+ down: missingOnLocal > 0 || differentDocuments > 0
504
+ };
505
+ };
506
+ var getSyncIndicator = (up, down) => {
507
+ if (up) {
508
+ if (down) {
509
+ return "\u21C5";
510
+ } else {
511
+ return "\u2191";
512
+ }
513
+ } else {
514
+ if (down) {
515
+ return "\u2193";
516
+ } else {
517
+ return "\u2713";
518
+ }
519
+ }
520
+ };
521
+ var printSpace = (spaceData) => make({
522
+ title: spaceData.name ?? spaceData.id
523
+ }).pipe(set("id", spaceData.id), set("state", spaceData.state), set("key", spaceData.key), set("members", spaceData.members), set("objects", spaceData.objects), set("epoch", spaceData.epoch ?? "<none>"), set("startup", spaceData.startup ? `${spaceData.startup}ms` : "<none>"), set("syncState", spaceData.syncState), set("automergeRoot", spaceData.automergeRoot ?? "<none>"), build);
524
+
525
+ // src/util/timeout.ts
526
+ import * as Config from "effect/Config";
527
+ import * as Duration2 from "effect/Duration";
528
+ import * as Effect5 from "effect/Effect";
529
+ import * as Option3 from "effect/Option";
530
+ var withTimeout = Effect5.fnUntraced(function* (effect2) {
531
+ const timeout2 = yield* Config.integer("TIMEOUT").pipe(Config.option);
532
+ const duration = timeout2.pipe(Option3.map(Duration2.millis), Option3.getOrElse(() => Duration2.infinity));
533
+ return yield* effect2.pipe(Effect5.timeout(duration));
534
+ });
535
+ export {
536
+ CommandConfig,
537
+ Common,
538
+ form_builder_exports as FormBuilder,
539
+ SpaceNotFoundError,
540
+ copyToClipboard,
541
+ flushAndSync,
542
+ formatSpace,
543
+ getSpace,
544
+ openBrowser,
545
+ print,
546
+ printList,
547
+ printSpace,
548
+ spaceIdWithDefault,
549
+ spaceLayer,
550
+ waitForSync,
551
+ withTimeout,
552
+ withTypes
553
+ };
554
+ //# sourceMappingURL=index.mjs.map