eraspace 0.2.0 → 0.3.0
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 +5 -1
- package/bin.js +344 -62
- package/package.json +1 -1
- package/sdk/src/client/client.ts +4 -2
- package/sdk/src/client/config.ts +17 -1
- package/sdk/src/client/connection.ts +67 -12
- package/sdk/src/client/files.ts +34 -9
- package/sdk/src/client/router.ts +1 -1
- package/sdk/src/client/storage.ts +31 -0
- package/sdk/src/client/sub-key.ts +16 -0
- package/sdk/src/client/subscription.ts +12 -1
- package/sdk/src/client/transport.ts +82 -15
- package/sdk/src/server/index.ts +41 -2
- package/templates/chat/client/index.tsx +1 -1
- package/templates/poll/client/index.tsx +1 -1
- package/templates/todo/client/index.tsx +1 -1
package/bin.js
CHANGED
|
@@ -241,6 +241,34 @@ __export(Effect_exports, {
|
|
|
241
241
|
zipWith: () => zipWith3
|
|
242
242
|
});
|
|
243
243
|
|
|
244
|
+
// node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Context.js
|
|
245
|
+
var Context_exports = {};
|
|
246
|
+
__export(Context_exports, {
|
|
247
|
+
Reference: () => Reference,
|
|
248
|
+
Service: () => Service,
|
|
249
|
+
ServiceTypeId: () => ServiceTypeId,
|
|
250
|
+
add: () => add,
|
|
251
|
+
addOrOmit: () => addOrOmit,
|
|
252
|
+
addUnsafe: () => addUnsafe,
|
|
253
|
+
empty: () => empty,
|
|
254
|
+
get: () => get,
|
|
255
|
+
getOption: () => getOption,
|
|
256
|
+
getOrElse: () => getOrElse2,
|
|
257
|
+
getOrUndefined: () => getOrUndefined2,
|
|
258
|
+
getOrUndefinedUnsafe: () => getOrUndefinedUnsafe,
|
|
259
|
+
getUnsafe: () => getUnsafe,
|
|
260
|
+
hasSameCache: () => hasSameCache,
|
|
261
|
+
isContext: () => isContext,
|
|
262
|
+
isKey: () => isKey,
|
|
263
|
+
isReference: () => isReference,
|
|
264
|
+
make: () => make5,
|
|
265
|
+
makeUnsafe: () => makeUnsafe,
|
|
266
|
+
merge: () => merge,
|
|
267
|
+
mergeAll: () => mergeAll,
|
|
268
|
+
omit: () => omit,
|
|
269
|
+
pick: () => pick
|
|
270
|
+
});
|
|
271
|
+
|
|
244
272
|
// node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Pipeable.js
|
|
245
273
|
var pipeArguments = (self, args2) => {
|
|
246
274
|
switch (args2.length) {
|
|
@@ -2273,6 +2301,7 @@ var Proto = {
|
|
|
2273
2301
|
};
|
|
2274
2302
|
var hasSameCache = (self, that) => self.cacheRoot === that.cacheRoot;
|
|
2275
2303
|
var isContext = (u) => hasProperty(u, TypeId3);
|
|
2304
|
+
var isKey = (u) => hasProperty(u, ServiceTypeId);
|
|
2276
2305
|
var isReference = (u) => !!u[ReferenceTypeId];
|
|
2277
2306
|
var empty = () => emptyContext2;
|
|
2278
2307
|
var emptyContext2 = /* @__PURE__ */ makeUnsafe(/* @__PURE__ */ new Map());
|
|
@@ -2293,6 +2322,12 @@ var addUnsafe = (self, key, service4) => {
|
|
|
2293
2322
|
parent: impl.overlay
|
|
2294
2323
|
}, impl.depth + 1);
|
|
2295
2324
|
};
|
|
2325
|
+
var addOrOmit = /* @__PURE__ */ dual(3, (self, key, service4) => service4._tag === "None" ? omit(key)(self) : add(self, key, service4.value));
|
|
2326
|
+
var getOrElse2 = /* @__PURE__ */ dual(3, (self, key, orElse6) => {
|
|
2327
|
+
const value4 = lookup(self, key.key);
|
|
2328
|
+
if (value4 !== notFound) return value4;
|
|
2329
|
+
return isReference(key) ? getDefaultValue(key) : orElse6();
|
|
2330
|
+
});
|
|
2296
2331
|
var getOrUndefined2 = /* @__PURE__ */ dual(2, (self, key) => getOrUndefinedUnsafe(self, key.key));
|
|
2297
2332
|
var getOrUndefinedUnsafe = (self, key) => {
|
|
2298
2333
|
const value4 = lookup(self, key);
|
|
@@ -2342,6 +2377,26 @@ var mergeAll = (...ctxs) => {
|
|
|
2342
2377
|
}
|
|
2343
2378
|
return makeUnsafe(map18);
|
|
2344
2379
|
};
|
|
2380
|
+
var pick = (...services) => (self) => {
|
|
2381
|
+
if (services.length <= 1) {
|
|
2382
|
+
const map18 = /* @__PURE__ */ new Map();
|
|
2383
|
+
if (services.length === 1) {
|
|
2384
|
+
const key = services[0].key;
|
|
2385
|
+
const value4 = lookup(self, key);
|
|
2386
|
+
if (value4 !== notFound) map18.set(key, value4);
|
|
2387
|
+
}
|
|
2388
|
+
return makeUnsafe(map18);
|
|
2389
|
+
}
|
|
2390
|
+
const keep = new Set(services.map((key) => key.key));
|
|
2391
|
+
return withFlat(self, (map18) => map18.forEach((_, key) => {
|
|
2392
|
+
if (!keep.has(key)) map18.delete(key);
|
|
2393
|
+
}));
|
|
2394
|
+
};
|
|
2395
|
+
var omit = (...keys4) => (self) => withFlat(self, (map18) => {
|
|
2396
|
+
for (let i = 0; i < keys4.length; i++) {
|
|
2397
|
+
map18.delete(keys4[i].key);
|
|
2398
|
+
}
|
|
2399
|
+
});
|
|
2345
2400
|
var Reference = Service;
|
|
2346
2401
|
|
|
2347
2402
|
// node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Duration.js
|
|
@@ -2988,7 +3043,7 @@ var merge2 = /* @__PURE__ */ match3({
|
|
|
2988
3043
|
onFailure: identity,
|
|
2989
3044
|
onSuccess: identity
|
|
2990
3045
|
});
|
|
2991
|
-
var
|
|
3046
|
+
var getOrElse3 = /* @__PURE__ */ dual(2, (self, onFailure) => isFailure2(self) ? onFailure(self.failure) : self.success);
|
|
2992
3047
|
var getOrThrowWith2 = /* @__PURE__ */ dual(2, (self, onFailure) => {
|
|
2993
3048
|
if (isSuccess2(self)) {
|
|
2994
3049
|
return self.success;
|
|
@@ -16361,7 +16416,7 @@ function transformOptionalEffect(f) {
|
|
|
16361
16416
|
transform: f
|
|
16362
16417
|
});
|
|
16363
16418
|
}
|
|
16364
|
-
function
|
|
16419
|
+
function omit2() {
|
|
16365
16420
|
return transformOptional(() => none2());
|
|
16366
16421
|
}
|
|
16367
16422
|
function withDefault(defaultValue) {
|
|
@@ -18565,9 +18620,9 @@ function isPattern(regExp, annotations) {
|
|
|
18565
18620
|
});
|
|
18566
18621
|
}
|
|
18567
18622
|
var bodyOwners = /* @__PURE__ */ new WeakMap();
|
|
18568
|
-
function copy2(ast,
|
|
18569
|
-
const out = Object.assign(Object.create(Object.getPrototypeOf(ast)), ast,
|
|
18570
|
-
if (Reflect.ownKeys(
|
|
18623
|
+
function copy2(ast, changes3) {
|
|
18624
|
+
const out = Object.assign(Object.create(Object.getPrototypeOf(ast)), ast, changes3);
|
|
18625
|
+
if (Reflect.ownKeys(changes3).every((key) => key === "context" || key === "encoding")) {
|
|
18571
18626
|
bodyOwners.set(out, getContextOwner(ast));
|
|
18572
18627
|
}
|
|
18573
18628
|
return out;
|
|
@@ -24947,10 +25002,10 @@ function toFormatter(ast, options3) {
|
|
|
24947
25002
|
}
|
|
24948
25003
|
|
|
24949
25004
|
// node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Struct.js
|
|
24950
|
-
var
|
|
25005
|
+
var pick2 = /* @__PURE__ */ dual(2, (self, keys4) => {
|
|
24951
25006
|
return buildStruct(self, (k, v) => hasPropertyKey(keys4, k) ? [k, v] : void 0);
|
|
24952
25007
|
});
|
|
24953
|
-
var
|
|
25008
|
+
var omit3 = /* @__PURE__ */ dual(2, (self, keys4) => {
|
|
24954
25009
|
return buildStruct(self, (k, v) => !hasPropertyKey(keys4, k) ? [k, v] : void 0);
|
|
24955
25010
|
});
|
|
24956
25011
|
var assign = /* @__PURE__ */ dual(2, (self, that) => {
|
|
@@ -25070,10 +25125,10 @@ var OptionalImpl = class {
|
|
|
25070
25125
|
this.replaceResult = replaceResult;
|
|
25071
25126
|
}
|
|
25072
25127
|
replace(a, s) {
|
|
25073
|
-
return
|
|
25128
|
+
return getOrElse3(this.replaceResult(a, s), () => s);
|
|
25074
25129
|
}
|
|
25075
25130
|
modify(f) {
|
|
25076
|
-
return (s) =>
|
|
25131
|
+
return (s) => getOrElse3(flatMap2(this.getResult(s), (a) => this.replaceResult(f(a), s)), () => s);
|
|
25077
25132
|
}
|
|
25078
25133
|
compose(that) {
|
|
25079
25134
|
return make36(compose3(this.node, that.node));
|
|
@@ -25121,14 +25176,14 @@ var OptionalImpl = class {
|
|
|
25121
25176
|
})));
|
|
25122
25177
|
}
|
|
25123
25178
|
pick(keys4) {
|
|
25124
|
-
return this.compose(makeLens(
|
|
25125
|
-
...
|
|
25179
|
+
return this.compose(makeLens(pick2(keys4), (p, a) => ({
|
|
25180
|
+
...omit3(a, keys4),
|
|
25126
25181
|
...p
|
|
25127
25182
|
})));
|
|
25128
25183
|
}
|
|
25129
25184
|
omit(keys4) {
|
|
25130
|
-
return this.compose(makeLens(
|
|
25131
|
-
...
|
|
25185
|
+
return this.compose(makeLens(omit3(keys4), (o, a) => ({
|
|
25186
|
+
...pick2(a, keys4),
|
|
25132
25187
|
...o
|
|
25133
25188
|
})));
|
|
25134
25189
|
}
|
|
@@ -25174,7 +25229,7 @@ var OptionalImpl = class {
|
|
|
25174
25229
|
);
|
|
25175
25230
|
}
|
|
25176
25231
|
modifyAll(f) {
|
|
25177
|
-
return (s) =>
|
|
25232
|
+
return (s) => getOrElse3(flatMap2(this.getResult(s), (as5) => this.replaceResult(as5.map(f), s)), () => s);
|
|
25178
25233
|
}
|
|
25179
25234
|
};
|
|
25180
25235
|
var IsoImpl = class extends OptionalImpl {
|
|
@@ -25213,7 +25268,7 @@ var PrismImpl = class extends OptionalImpl {
|
|
|
25213
25268
|
return this.set(a);
|
|
25214
25269
|
}
|
|
25215
25270
|
modify(f) {
|
|
25216
|
-
return (s) =>
|
|
25271
|
+
return (s) => getOrElse3(map2(this.getResult(s), (a) => this.set(f(a))), () => s);
|
|
25217
25272
|
}
|
|
25218
25273
|
};
|
|
25219
25274
|
function make36(node) {
|
|
@@ -26001,7 +26056,7 @@ function toIssueEffect(self) {
|
|
|
26001
26056
|
return catchCause3(self, (cause) => failCauseSync2(() => map6(cause, (error2) => error2.issue)));
|
|
26002
26057
|
}
|
|
26003
26058
|
function withDecodingDefaultKey(defaultValue, options3) {
|
|
26004
|
-
const encode5 = options3?.encodingStrategy === "omit" ?
|
|
26059
|
+
const encode5 = options3?.encodingStrategy === "omit" ? omit2() : passthrough2();
|
|
26005
26060
|
return (self) => {
|
|
26006
26061
|
return optionalKey2(toEncoded2(self)).pipe(decodeTo2(self, {
|
|
26007
26062
|
decode: withDefault(toIssueEffect(defaultValue)),
|
|
@@ -26015,7 +26070,7 @@ function withDecodingDefaultTypeKey(defaultValue, options3) {
|
|
|
26015
26070
|
};
|
|
26016
26071
|
}
|
|
26017
26072
|
function withDecodingDefault(defaultValue, options3) {
|
|
26018
|
-
const encode5 = options3?.encodingStrategy === "omit" ?
|
|
26073
|
+
const encode5 = options3?.encodingStrategy === "omit" ? omit2() : passthrough2();
|
|
26019
26074
|
return (self) => {
|
|
26020
26075
|
return optional2(toEncoded2(self)).pipe(decodeTo2(self, {
|
|
26021
26076
|
decode: withDefault(toIssueEffect(defaultValue)),
|
|
@@ -38939,7 +38994,7 @@ var runWith2 = (command2, config2) => {
|
|
|
38939
38994
|
// cli/package.json
|
|
38940
38995
|
var package_default = {
|
|
38941
38996
|
name: "eraspace-cli",
|
|
38942
|
-
version: "0.
|
|
38997
|
+
version: "0.3.0",
|
|
38943
38998
|
private: true,
|
|
38944
38999
|
license: "MIT",
|
|
38945
39000
|
type: "module",
|
|
@@ -39266,6 +39321,48 @@ function formatLog(l) {
|
|
|
39266
39321
|
const data = l.data === void 0 || l.data === null ? "" : " " + c.gray(JSON.stringify(l.data));
|
|
39267
39322
|
return `${c.gray(time3)} ${color(level.padEnd(5))} ${fn3}${l.msg ?? ""}${data}`;
|
|
39268
39323
|
}
|
|
39324
|
+
var SKIPPED = {
|
|
39325
|
+
fetch: "uses fetch",
|
|
39326
|
+
identity: "reads the caller's identity",
|
|
39327
|
+
running: "was running",
|
|
39328
|
+
recovering: "cache recovering",
|
|
39329
|
+
"new index": "reads an index this deploy adds",
|
|
39330
|
+
committed: "a commit changed it during the check",
|
|
39331
|
+
budget: "out of time",
|
|
39332
|
+
limit: "too many entries",
|
|
39333
|
+
interrupted: "interrupted"
|
|
39334
|
+
};
|
|
39335
|
+
var call = (fn3, args2) => {
|
|
39336
|
+
const text2 = Array.isArray(args2) ? args2.map((a) => JSON.stringify(a)).join(", ") : JSON.stringify(args2);
|
|
39337
|
+
return `${fn3}(${text2 && text2.length > 80 ? `${text2.slice(0, 77)}...` : text2 ?? ""})`;
|
|
39338
|
+
};
|
|
39339
|
+
function formatShadow(report) {
|
|
39340
|
+
if (report.note) return c.dim(`Live queries: none checked (${report.note})`);
|
|
39341
|
+
const total = report.total ?? 0;
|
|
39342
|
+
if (total === 0) return c.dim("Live queries: none cached, nothing to check");
|
|
39343
|
+
const errors = report.errors ?? 0;
|
|
39344
|
+
const changed = report.changed ?? 0;
|
|
39345
|
+
const parts2 = [
|
|
39346
|
+
`${report.unchanged ?? 0} unchanged`,
|
|
39347
|
+
changed ? c.yellow(`${changed} change value`) : "0 change value",
|
|
39348
|
+
errors ? c.red(`${errors} now throw`) : "0 now throw",
|
|
39349
|
+
...report.fixed ? [c.green(`${report.fixed} fixed`)] : [],
|
|
39350
|
+
...report.skipped ? [c.dim(`${report.skipped} skipped`)] : []
|
|
39351
|
+
];
|
|
39352
|
+
const at = report.commitSeq ? ` at commit ${report.commitSeq}` : "";
|
|
39353
|
+
const lines2 = [`Live queries: ${report.checked ?? 0} of ${total} checked against the new code${at}: ${parts2.join(", ")}`];
|
|
39354
|
+
for (const e of report.entries ?? []) {
|
|
39355
|
+
const what = call(e.fn, e.args);
|
|
39356
|
+
if (e.outcome === "error") lines2.push(` ${c.red("throws ")} ${what}: ${e.error ? `${e.error.name}: ${e.error.message}` : ""}`);
|
|
39357
|
+
else if (e.outcome === "changed") lines2.push(` ${c.yellow("changes")} ${what}${e.error ? `: ${e.error.name}: ${e.error.message}` : ""}`);
|
|
39358
|
+
else if (e.outcome === "fixed") lines2.push(` ${c.green("fixed ")} ${what}`);
|
|
39359
|
+
else lines2.push(c.dim(` skipped ${what}: ${SKIPPED[e.reason ?? ""] ?? e.reason ?? ""}`));
|
|
39360
|
+
}
|
|
39361
|
+
const listed = report.entries?.length ?? 0;
|
|
39362
|
+
const notable = errors + changed + (report.fixed ?? 0) + (report.skipped ?? 0);
|
|
39363
|
+
if (notable > listed) lines2.push(c.dim(` ... and ${notable - listed} more`));
|
|
39364
|
+
return lines2.join("\n");
|
|
39365
|
+
}
|
|
39269
39366
|
|
|
39270
39367
|
// cli/src/api.ts
|
|
39271
39368
|
var Timestamp = Schema_exports.NullOr(Schema_exports.Union([Schema_exports.Number, Schema_exports.String]));
|
|
@@ -39280,10 +39377,34 @@ var App = Schema_exports.Struct({
|
|
|
39280
39377
|
expiresAt: Schema_exports.optional(Timestamp),
|
|
39281
39378
|
publicInspection: Schema_exports.optional(Schema_exports.Boolean)
|
|
39282
39379
|
});
|
|
39380
|
+
var Count = Schema_exports.optional(Schema_exports.Number);
|
|
39381
|
+
var ShadowReport = Schema_exports.Struct({
|
|
39382
|
+
total: Count,
|
|
39383
|
+
checked: Count,
|
|
39384
|
+
unchanged: Count,
|
|
39385
|
+
changed: Count,
|
|
39386
|
+
errors: Count,
|
|
39387
|
+
fixed: Count,
|
|
39388
|
+
skipped: Count,
|
|
39389
|
+
commitSeq: Count,
|
|
39390
|
+
note: Schema_exports.optional(Schema_exports.String),
|
|
39391
|
+
entries: Schema_exports.optional(
|
|
39392
|
+
Schema_exports.Array(
|
|
39393
|
+
Schema_exports.Struct({
|
|
39394
|
+
fn: Schema_exports.String,
|
|
39395
|
+
args: Schema_exports.optional(Schema_exports.Unknown),
|
|
39396
|
+
outcome: Schema_exports.String,
|
|
39397
|
+
reason: Schema_exports.optional(Schema_exports.String),
|
|
39398
|
+
error: Schema_exports.optional(Schema_exports.Struct({ name: Schema_exports.String, message: Schema_exports.String }))
|
|
39399
|
+
})
|
|
39400
|
+
)
|
|
39401
|
+
)
|
|
39402
|
+
});
|
|
39283
39403
|
var Deployed = Schema_exports.Struct({
|
|
39284
39404
|
...App.fields,
|
|
39285
39405
|
version: Schema_exports.optional(Schema_exports.Number),
|
|
39286
|
-
claimToken: Schema_exports.optional(Schema_exports.String)
|
|
39406
|
+
claimToken: Schema_exports.optional(Schema_exports.String),
|
|
39407
|
+
shadow: Schema_exports.optional(ShadowReport)
|
|
39287
39408
|
});
|
|
39288
39409
|
var AppList = Schema_exports.Struct({ apps: Schema_exports.Array(App) });
|
|
39289
39410
|
var StateChange = Schema_exports.Struct({ state: Schema_exports.String });
|
|
@@ -39448,15 +39569,20 @@ var login = Effect_exports.fnUntraced(function* (config2, browser) {
|
|
|
39448
39569
|
}
|
|
39449
39570
|
return yield* fail12("The sign-in code expired. Run eraspace auth login again.");
|
|
39450
39571
|
});
|
|
39572
|
+
var LogoutResult = Schema_exports.Struct({ ok: Schema_exports.Literal(true) });
|
|
39451
39573
|
var logout = Effect_exports.fnUntraced(function* (config2) {
|
|
39452
39574
|
const session = yield* sessionFor(config2.origin);
|
|
39453
39575
|
if (!session) {
|
|
39454
39576
|
yield* Console_exports.log(`Not signed in to ${config2.origin}.`);
|
|
39455
39577
|
return;
|
|
39456
39578
|
}
|
|
39457
|
-
yield*
|
|
39579
|
+
const response = yield* api(config2, "POST", "/_api/auth/logout", { bearer: Redacted_exports.make(session.token), timeout: "10 seconds" });
|
|
39580
|
+
if (response.status !== 401) {
|
|
39581
|
+
if (response.status >= 400 || response.json.ok === false) return yield* Effect_exports.fail(yield* failure(response));
|
|
39582
|
+
yield* decode5(LogoutResult, response.json, "sign-out");
|
|
39583
|
+
}
|
|
39458
39584
|
yield* removeSession(config2.origin);
|
|
39459
|
-
yield* Console_exports.log(`Signed out of ${config2.origin}.`);
|
|
39585
|
+
yield* Console_exports.log(response.status === 401 ? `Removed invalid session for ${config2.origin}.` : `Signed out of ${config2.origin}.`);
|
|
39460
39586
|
});
|
|
39461
39587
|
var okWhoami = ok(Whoami);
|
|
39462
39588
|
var whoami = Effect_exports.fnUntraced(function* (config2) {
|
|
@@ -39491,6 +39617,7 @@ function scanImports(file2, source) {
|
|
|
39491
39617
|
}
|
|
39492
39618
|
return { imports: imports.sort((a, b) => (a.at ?? 0) - (b.at ?? 0)) };
|
|
39493
39619
|
}
|
|
39620
|
+
var MAX_MODULE_BYTES = 256 * 1024;
|
|
39494
39621
|
var EXTENSIONS = [".ts", ".mts", ".js", ".mjs", ".tsx"];
|
|
39495
39622
|
function importCandidates(base) {
|
|
39496
39623
|
const stem = /\.m?js$/.test(base) ? base.replace(/\.m?js$/, "") : void 0;
|
|
@@ -39526,6 +39653,10 @@ var collectServerFiles = Effect_exports.fnUntraced(function* (root) {
|
|
|
39526
39653
|
const rel = toPosix(relative2(root, abs2));
|
|
39527
39654
|
const source = yield* fs.readFileString(abs2);
|
|
39528
39655
|
files[rel] = source;
|
|
39656
|
+
const bytes2 = Buffer.byteLength(source, "utf8");
|
|
39657
|
+
if (bytes2 > MAX_MODULE_BYTES) {
|
|
39658
|
+
errors.push({ file: rel, line: 0, column: 0, message: `module is ${bytes2} bytes, over the server's ${MAX_MODULE_BYTES} byte (256 KiB) limit; split it into smaller modules` });
|
|
39659
|
+
}
|
|
39529
39660
|
const { imports, error: error2 } = scanImports(abs2, source);
|
|
39530
39661
|
if (error2) {
|
|
39531
39662
|
errors.push({ file: rel, ...lineCol(source, error2.at), message: error2.message });
|
|
@@ -39804,7 +39935,6 @@ var withoutEnv = Effect_exports.fnUntraced(function* (payload) {
|
|
|
39804
39935
|
}
|
|
39805
39936
|
return { ...payload, env: {} };
|
|
39806
39937
|
});
|
|
39807
|
-
var okDeployed = ok(Deployed);
|
|
39808
39938
|
var requestedName = (config2, opts) => opts.name !== void 0 ? { name: opts.name } : { name: config2.name ?? toAppName(basename(config2.root)), uniqueName: true };
|
|
39809
39939
|
var createApp = Effect_exports.fnUntraced(function* (config2, payload, extra, opts, signedIn) {
|
|
39810
39940
|
const naming = requestedName(config2, opts);
|
|
@@ -39837,23 +39967,27 @@ var deploy = Effect_exports.fnUntraced(function* (config2, opts = {}) {
|
|
|
39837
39967
|
const deleteTables = yield* confirmedDeletes(opts.deleteTables);
|
|
39838
39968
|
const extra = {
|
|
39839
39969
|
...opts.publicInspect ? { publicInspection: true } : {},
|
|
39840
|
-
...Object.keys(deleteTables).length ? { deleteTables } : {}
|
|
39970
|
+
...Object.keys(deleteTables).length ? { deleteTables } : {},
|
|
39971
|
+
...opts.shadow ? { shadow: true } : {},
|
|
39972
|
+
...opts.failOnQueryErrors ? { failOnQueryErrors: true } : {}
|
|
39841
39973
|
};
|
|
39842
39974
|
const signedIn = (yield* bearerFor(config2.origin)) !== void 0;
|
|
39843
39975
|
const t = yield* target(config2);
|
|
39844
39976
|
let result4;
|
|
39845
39977
|
if (t.ref) {
|
|
39846
39978
|
const payload = t.claim ? yield* withoutEnv(build3.payload) : build3.payload;
|
|
39847
|
-
|
|
39848
|
-
|
|
39849
|
-
|
|
39850
|
-
|
|
39851
|
-
|
|
39852
|
-
|
|
39853
|
-
|
|
39854
|
-
|
|
39855
|
-
|
|
39856
|
-
|
|
39979
|
+
const path = `/_api/apps/${enc(t.ref)}/deploy`;
|
|
39980
|
+
const response = yield* api(config2, "POST", path, {
|
|
39981
|
+
body: { ...payload, ...extra },
|
|
39982
|
+
claim: t.claim,
|
|
39983
|
+
timeout: DEPLOY_TIMEOUT
|
|
39984
|
+
});
|
|
39985
|
+
if (response.status >= 400 || response.json.ok === false) {
|
|
39986
|
+
const refused = Schema_exports.decodeUnknownOption(ShadowReport)(response.json.shadow);
|
|
39987
|
+
if (Option_exports.isSome(refused)) yield* Console_exports.log(formatShadow(refused.value));
|
|
39988
|
+
return yield* Effect_exports.fail(yield* failure(response, config2.root));
|
|
39989
|
+
}
|
|
39990
|
+
result4 = yield* decode5(Deployed, response.json, `POST ${path}`);
|
|
39857
39991
|
if (t.claim && result4.claimed)
|
|
39858
39992
|
yield* removeLocalDeploy(config2.root, config2.origin);
|
|
39859
39993
|
} else if (signedIn) {
|
|
@@ -39878,6 +40012,7 @@ var deploy = Effect_exports.fnUntraced(function* (config2, opts = {}) {
|
|
|
39878
40012
|
expiresAt: Number.isFinite(expiresAt) ? expiresAt : null
|
|
39879
40013
|
});
|
|
39880
40014
|
}
|
|
40015
|
+
if (result4.shadow) yield* Console_exports.log(formatShadow(result4.shadow));
|
|
39881
40016
|
const label = result4.names?.[0] ?? result4.id;
|
|
39882
40017
|
yield* Console_exports.log(
|
|
39883
40018
|
`${label}${result4.version === void 0 ? "" : ` v${result4.version}`}: ${result4.url ?? config2.url}`
|
|
@@ -39964,7 +40099,10 @@ var dev = Effect_exports.fnUntraced(function* (config2, opts) {
|
|
|
39964
40099
|
});
|
|
39965
40100
|
|
|
39966
40101
|
// cli/src/logs.ts
|
|
39967
|
-
var
|
|
40102
|
+
var LogTimeouts = Context_exports.Reference(
|
|
40103
|
+
"eraspace/cli/LogTimeouts",
|
|
40104
|
+
{ defaultValue: () => ({ idle: Duration_exports.seconds(75), stalled: Duration_exports.seconds(30), errorBody: Duration_exports.seconds(10) }) }
|
|
40105
|
+
);
|
|
39968
40106
|
var Printed = class {
|
|
39969
40107
|
lines = [];
|
|
39970
40108
|
limit;
|
|
@@ -40005,12 +40143,14 @@ var readOnce = Effect_exports.fnUntraced(function* (config2, path, claim2, follo
|
|
|
40005
40143
|
const response = yield* request3(config2, "GET", path, { claim: claim2 }).pipe(
|
|
40006
40144
|
Effect_exports.timeoutOrElse({ duration: "30 seconds", orElse: () => Effect_exports.fail(new Transient({ message: `The platform at ${config2.origin} did not answer within 30s.` })) })
|
|
40007
40145
|
);
|
|
40146
|
+
const timeouts = yield* LogTimeouts;
|
|
40147
|
+
const errorText = response.text.pipe(Effect_exports.timeout(timeouts.errorBody), Effect_exports.orElseSucceed(() => ""));
|
|
40008
40148
|
if (isGatewayError(response.status)) {
|
|
40009
|
-
yield*
|
|
40149
|
+
yield* errorText;
|
|
40010
40150
|
return yield* new Transient({ message: `The platform at ${config2.origin} is unavailable (HTTP ${response.status}).` });
|
|
40011
40151
|
}
|
|
40012
40152
|
if (response.status >= 400) {
|
|
40013
|
-
const text2 = yield*
|
|
40153
|
+
const text2 = yield* errorText;
|
|
40014
40154
|
let json2 = { ok: false, error: text2.trim() || `HTTP ${response.status}` };
|
|
40015
40155
|
try {
|
|
40016
40156
|
json2 = JSON.parse(text2);
|
|
@@ -40018,12 +40158,15 @@ var readOnce = Effect_exports.fnUntraced(function* (config2, path, claim2, follo
|
|
|
40018
40158
|
}
|
|
40019
40159
|
return yield* Effect_exports.fail(yield* failure({ status: response.status, json: json2 }, config2.root));
|
|
40020
40160
|
}
|
|
40021
|
-
|
|
40161
|
+
const lines2 = response.stream.pipe(
|
|
40162
|
+
Stream_exports.mapError((error2) => new Transient({ message: `The log stream broke: ${describe(error2.cause ?? error2)}` })),
|
|
40163
|
+
Stream_exports.timeoutOrElse({
|
|
40164
|
+
duration: follow ? timeouts.idle : timeouts.stalled,
|
|
40165
|
+
orElse: () => Stream_exports.fail(new Transient({ message: follow ? "The log stream went quiet." : `The platform at ${config2.origin} stopped sending logs.` }))
|
|
40166
|
+
}),
|
|
40022
40167
|
Stream_exports.decodeText(),
|
|
40023
|
-
Stream_exports.splitLines
|
|
40024
|
-
Stream_exports.mapError((error2) => new Transient({ message: `The log stream broke: ${describe(error2.cause ?? error2)}` }))
|
|
40168
|
+
Stream_exports.splitLines
|
|
40025
40169
|
);
|
|
40026
|
-
if (follow) lines2 = lines2.pipe(Stream_exports.timeoutOrElse({ duration: IDLE, orElse: () => Stream_exports.fail(new Transient({ message: "The log stream went quiet." })) }));
|
|
40027
40170
|
const fresh2 = printed.connection();
|
|
40028
40171
|
yield* lines2.pipe(
|
|
40029
40172
|
Stream_exports.filter((line) => line.trim() !== ""),
|
|
@@ -40090,6 +40233,68 @@ var lifecycle = Effect_exports.fnUntraced(function* (config2, action, explicit,
|
|
|
40090
40233
|
const result4 = yield* okState(config2, "POST", `/_api/apps/${enc(t.ref)}/${action}`, { claim: t.claim });
|
|
40091
40234
|
yield* Console_exports.log(`${t.ref}: ${result4.state}`);
|
|
40092
40235
|
});
|
|
40236
|
+
var explain = Effect_exports.fnUntraced(function* (config2, fn3, inputs, json2) {
|
|
40237
|
+
const args2 = yield* parseCallArgs(inputs);
|
|
40238
|
+
const t = yield* requireTarget(config2);
|
|
40239
|
+
const report = yield* okJson(config2, "POST", `/_api/apps/${enc(t.ref)}/explain`, { body: { fn: fn3, args: args2 }, claim: t.claim });
|
|
40240
|
+
if (json2) return yield* Console_exports.log(JSON.stringify(report, null, 2));
|
|
40241
|
+
const scans = report.scans ?? [];
|
|
40242
|
+
yield* Console_exports.log(`${fn3}: read ${String(report.rowsRead)} row${report.rowsRead === 1 ? "" : "s"} in ${scans.length} scan${scans.length === 1 ? "" : "s"} and returned ${String(report.returned)}`);
|
|
40243
|
+
for (const s of scans) yield* Console_exports.log(` ${s.table} via ${s.index} (${s.mode}): read ${s.rowsRead}, kept ${s.kept} of ${s.rows}`);
|
|
40244
|
+
const suggestions = report.suggestions ?? [];
|
|
40245
|
+
if (!suggestions.length) yield* Console_exports.log(c.dim("No index suggestions."));
|
|
40246
|
+
for (const s of suggestions) yield* Console_exports.log(`${c.yellow("suggest")} ${s.message}`);
|
|
40247
|
+
});
|
|
40248
|
+
var profile = Effect_exports.fnUntraced(function* (config2, explicit, seconds2, out) {
|
|
40249
|
+
const t = yield* requireTarget(config2, explicit);
|
|
40250
|
+
yield* Console_exports.error(c.dim(`Profiling ${t.ref} for ${seconds2}s...`));
|
|
40251
|
+
const result4 = yield* okJson(config2, "POST", `/_api/apps/${enc(t.ref)}/profile`, { body: { seconds: seconds2 }, claim: t.claim, timeout: Duration_exports.seconds(seconds2 + 30) });
|
|
40252
|
+
const file2 = out ?? `${t.ref}-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}.cpuprofile`;
|
|
40253
|
+
const fs = yield* FileSystem_exports.FileSystem;
|
|
40254
|
+
yield* fs.writeFileString(file2, JSON.stringify(result4));
|
|
40255
|
+
const nodes = new Map((result4.nodes ?? []).map((n) => [n.id, n]));
|
|
40256
|
+
const counts = /* @__PURE__ */ new Map();
|
|
40257
|
+
let busy = 0;
|
|
40258
|
+
for (const id2 of result4.samples ?? []) {
|
|
40259
|
+
const f = nodes.get(id2)?.callFrame;
|
|
40260
|
+
if (!f || f.functionName === "(idle)" || f.functionName === "(root)") continue;
|
|
40261
|
+
busy++;
|
|
40262
|
+
const at = f.url ? ` ${f.url}:${f.lineNumber + 1}` : "";
|
|
40263
|
+
const name = `${f.functionName || "(anonymous)"}${at}`;
|
|
40264
|
+
counts.set(name, (counts.get(name) ?? 0) + 1);
|
|
40265
|
+
}
|
|
40266
|
+
const samples = (result4.samples ?? []).length;
|
|
40267
|
+
yield* Console_exports.log(`${t.ref}: busy in ${busy} of ${samples} samples. Open ${file2} in Chrome DevTools (Performance > Load profile).`);
|
|
40268
|
+
for (const [name, n] of [...counts].sort((a, b) => b[1] - a[1]).slice(0, 10)) {
|
|
40269
|
+
yield* Console_exports.log(` ${(100 * n / Math.max(busy, 1)).toFixed(1).padStart(5)}% ${name}`);
|
|
40270
|
+
}
|
|
40271
|
+
});
|
|
40272
|
+
var changes2 = Effect_exports.fnUntraced(function* (config2, since, limit) {
|
|
40273
|
+
const t = yield* requireTarget(config2);
|
|
40274
|
+
const response = yield* request3(config2, "GET", `/_api/apps/${enc(t.ref)}/changes?since=${since}&limit=${limit}`, { claim: t.claim });
|
|
40275
|
+
const text2 = yield* response.text.pipe(Effect_exports.orElseSucceed(() => ""));
|
|
40276
|
+
if (response.status >= 400) {
|
|
40277
|
+
let json2 = { ok: false, error: text2.trim() || `HTTP ${response.status}` };
|
|
40278
|
+
try {
|
|
40279
|
+
json2 = JSON.parse(text2);
|
|
40280
|
+
} catch {
|
|
40281
|
+
}
|
|
40282
|
+
return yield* Effect_exports.fail(yield* failure({ status: response.status, json: json2 }));
|
|
40283
|
+
}
|
|
40284
|
+
const lines2 = text2.split("\n").filter(Boolean);
|
|
40285
|
+
for (const line of lines2) yield* Console_exports.log(line);
|
|
40286
|
+
const head5 = Number(response.headers["x-eraspace-commit-seq"] ?? 0);
|
|
40287
|
+
const last = lines2.length ? JSON.parse(lines2.at(-1)).seq : since;
|
|
40288
|
+
const more = response.headers["x-eraspace-more"] === "1";
|
|
40289
|
+
yield* Console_exports.error(c.dim(more ? `Latest commit ${head5}; continue with --since ${last}` : `Up to date at commit ${head5}`));
|
|
40290
|
+
});
|
|
40291
|
+
var undo = Effect_exports.fnUntraced(function* (config2, to, yes) {
|
|
40292
|
+
const t = yield* requireTarget(config2);
|
|
40293
|
+
if (!yes) return yield* fail12(`eraspace undo ${to} puts every row of ${t.ref} changed after commit ${to} back as it was. Re-run with --yes.`);
|
|
40294
|
+
const result4 = yield* okJson(config2, "POST", `/_api/apps/${enc(t.ref)}/undo`, { body: { toSeq: to }, claim: t.claim });
|
|
40295
|
+
const undone = Number(result4.undone ?? 0);
|
|
40296
|
+
yield* Console_exports.log(undone ? `${t.ref}: restored ${undone} row${undone === 1 ? "" : "s"} to commit ${to} as commit ${String(result4.commitSeq)}` : `${t.ref}: nothing changed after commit ${to}`);
|
|
40297
|
+
});
|
|
40093
40298
|
var listTokens = Effect_exports.fnUntraced(function* (config2) {
|
|
40094
40299
|
const { tokens } = yield* ok(TokenList)(config2, "GET", "/_api/tokens");
|
|
40095
40300
|
if (!tokens.length) yield* Console_exports.log("No tokens.");
|
|
@@ -40122,7 +40327,7 @@ Pass each argument as JSON, for example eraspace call send '"general"' '{"text":
|
|
|
40122
40327
|
}
|
|
40123
40328
|
return Effect_exports.succeed(args2);
|
|
40124
40329
|
}
|
|
40125
|
-
var
|
|
40330
|
+
var call2 = Effect_exports.fnUntraced(function* (config2, fn3, inputs) {
|
|
40126
40331
|
const args2 = yield* parseCallArgs(inputs);
|
|
40127
40332
|
const t = yield* requireTarget(config2);
|
|
40128
40333
|
const { status, text: text2 } = yield* Effect_exports.gen(function* () {
|
|
@@ -40222,6 +40427,8 @@ export default capsule({
|
|
|
40222
40427
|
\`paginate({ cursor, numItems })\`. Every table has an implicit \`by_creation\` index. Await every db call.
|
|
40223
40428
|
- Queries and actions have a read-only db. Write in mutations or writable endpoints. Actions can call
|
|
40224
40429
|
\`ctx.runQuery\`, \`ctx.runMutation\` and global \`fetch\`.
|
|
40430
|
+
- Mutations schedule later work with \`ctx.scheduler.runAfter(ms, "mutationName", ...args)\`, which returns a job id.
|
|
40431
|
+
The job commits with the mutation and its run commits once; only mutations can be scheduled.
|
|
40225
40432
|
- Handler arguments are positional and not validated. Check them in the handler.
|
|
40226
40433
|
- \`ctx.auth.userId\` is a per-connection guest id that changes on reload. It is not a login: never use it for
|
|
40227
40434
|
ownership or access control. Every app is public.
|
|
@@ -40230,7 +40437,9 @@ export default capsule({
|
|
|
40230
40437
|
\`json(value)\`, \`text(string)\`, \`empty()\`, \`redirect(url)\` or a plain value (sent as JSON).
|
|
40231
40438
|
- Removing a populated table needs its row count confirmed: \`${cli} deploy --delete-table <table>=<rows>\` (the
|
|
40232
40439
|
refused deploy prints the exact flag). Deletion runs in background batches.
|
|
40233
|
-
- Changing a field's type or making it required fails the deploy while stored rows do not match
|
|
40440
|
+
- Changing a field's type or making it required fails the deploy while stored rows do not match. Declare a
|
|
40441
|
+
migration instead: \`table({ ... }).migrate(1, row => ({ ...row, done: false }))\` upgrades old rows when read
|
|
40442
|
+
and rewrites them in the background. Number migrations 1, 2, 3, ... and keep each one until its rows are done.
|
|
40234
40443
|
|
|
40235
40444
|
## Client API (\`eraspace/client\`)
|
|
40236
40445
|
|
|
@@ -40239,7 +40448,7 @@ import { createClient } from "eraspace/client";
|
|
|
40239
40448
|
import { useState } from "preact/hooks";
|
|
40240
40449
|
import type app from "../server/index";
|
|
40241
40450
|
|
|
40242
|
-
const client = createClient<typeof app>(
|
|
40451
|
+
const client = createClient<typeof app>();
|
|
40243
40452
|
|
|
40244
40453
|
export default function App() {
|
|
40245
40454
|
const items = client.useQuery("items", "some-list"); // undefined while loading, then live
|
|
@@ -40266,6 +40475,8 @@ export default function App() {
|
|
|
40266
40475
|
cleanup). \`client.usePresence(name, meta)\` returns just the members.
|
|
40267
40476
|
- Files: see "File uploads" below.
|
|
40268
40477
|
- Pages: \`Router\`, \`Route\`, \`Link\`, \`useLocation\`, \`useNavigate\`, \`useParams\` from \`eraspace/client\`.
|
|
40478
|
+
- Open tabs reload by themselves after each deploy. Pass \`createClient({ reloadOnDeploy: false })\` to keep the
|
|
40479
|
+
page and react to \`client.onDeployed(version => ...)\` instead.
|
|
40269
40480
|
- Client imports are limited to \`eraspace/client\`, \`preact\`, \`preact/hooks\`, \`@preact/signals\` and relative files.
|
|
40270
40481
|
|
|
40271
40482
|
## File uploads
|
|
@@ -40292,10 +40503,11 @@ const addPhoto = client.useMutation("addPhoto");
|
|
|
40292
40503
|
children for the label. \`onUpload(file)\` runs once per stored file; if it throws, the file is deleted again.
|
|
40293
40504
|
- \`<FilePreview file={fileRef or key}>\` shows images, video and audio inline, plain text in a frame, and other
|
|
40294
40505
|
types (PDF, zip...) as a download card. \`caption={false}\` hides the name/size line; \`class\` replaces its style.
|
|
40295
|
-
Pass the saved \`FileRef\`: a bare key costs a metadata request per preview.
|
|
40296
|
-
|
|
40297
|
-
|
|
40298
|
-
|
|
40506
|
+
Pass the saved \`FileRef\`: a bare key costs a metadata request per preview. Images, video and audio uploaded
|
|
40507
|
+
from the same page show at once from the browser's copy; \`<FileUpload>\` shows an image while it uploads.
|
|
40508
|
+
- Custom UI: \`const { upload, uploading, progress, error, file } = client.useUpload({ accept, maxBytes, onUpload })\`,
|
|
40509
|
+
then \`upload(input.files)\`; \`file\` is the Blob uploading now. Lower level: \`client.storage.upload(blob, { onProgress })\`,
|
|
40510
|
+
\`.url(key)\`, \`.localUrl(key)\`, \`.info(key)\` and \`.delete(key)\`.
|
|
40299
40511
|
- \`accept\` and \`maxBytes\` are checked in the browser only; the server stores any type up to its limit.
|
|
40300
40512
|
- Up to 5 MiB per file and 100 MiB per app. Anyone with a key can read or delete that file; never upload secrets.
|
|
40301
40513
|
|
|
@@ -40307,8 +40519,9 @@ Values crossing the database or RPC boundary must be JSON-compatible.
|
|
|
40307
40519
|
|
|
40308
40520
|
- Imports support relative deployed files and \`eraspace/server\`. npm packages, Node built-ins and dynamic
|
|
40309
40521
|
\`import()\` are unavailable. Apps need no installed server dependencies.
|
|
40310
|
-
- The host supplies \`fetch\`, \`URL\`, \`Headers\`, \`Request\`, \`Response\`,
|
|
40311
|
-
\`
|
|
40522
|
+
- The host supplies \`fetch\`, \`URL\`, \`URLPattern\`, \`Headers\`, \`Request\`, \`Response\`, Web Streams,
|
|
40523
|
+
\`Blob\`, \`File\`, \`FormData\`, \`crypto\` (including \`crypto.subtle\`), \`TextEncoder\`, \`TextDecoder\`,
|
|
40524
|
+
\`CompressionStream\`, timers and \`console\`. Bodies arrive and leave whole rather than incrementally.
|
|
40312
40525
|
- Persist state in the database. Module state is not durable and resets when an app unloads or a worker restarts.
|
|
40313
40526
|
- Await database calls. Mutations run through one writer per app and reply after their Postgres commit.
|
|
40314
40527
|
- Handlers have CPU, wall-clock and heap limits. Keep loops and reads bounded.
|
|
@@ -40456,6 +40669,16 @@ var deleteTableFlag = {
|
|
|
40456
40669
|
Flag_exports.optional
|
|
40457
40670
|
)
|
|
40458
40671
|
};
|
|
40672
|
+
var shadowFlags = {
|
|
40673
|
+
shadow: Flag_exports.Boolean("shadow").pipe(
|
|
40674
|
+
Flag_exports.withDefault(false),
|
|
40675
|
+
Flag_exports.withDescription("Before installing, rerun the app's live queries on the new code and report which results change or start throwing")
|
|
40676
|
+
),
|
|
40677
|
+
failOnQueryErrors: Flag_exports.Boolean("fail-on-query-errors").pipe(
|
|
40678
|
+
Flag_exports.withDefault(false),
|
|
40679
|
+
Flag_exports.withDescription("Like --shadow, but refuse the deploy if a live query that returns a value now would throw")
|
|
40680
|
+
)
|
|
40681
|
+
};
|
|
40459
40682
|
var browserFlag = {
|
|
40460
40683
|
browser: Flag_exports.Boolean("browser").pipe(Flag_exports.withDefault(true), Flag_exports.withDescription("Open the sign-in page in a browser; --no-browser only prints the URL"))
|
|
40461
40684
|
};
|
|
@@ -40479,11 +40702,17 @@ var typecheckCommand = Command_exports.make("typecheck", {}, () => Effect_export
|
|
|
40479
40702
|
);
|
|
40480
40703
|
var deployCommand = Command_exports.make(
|
|
40481
40704
|
"deploy",
|
|
40482
|
-
{ ...deployFlags, ...deleteTableFlag },
|
|
40483
|
-
(input) => Effect_exports.flatMap(
|
|
40705
|
+
{ ...deployFlags, ...deleteTableFlag, ...shadowFlags },
|
|
40706
|
+
(input) => Effect_exports.flatMap(
|
|
40707
|
+
config,
|
|
40708
|
+
(c2) => deploy(c2, { ...deployOptions(input), deleteTables: value3(input.deleteTable), shadow: input.shadow, failOnQueryErrors: input.failOnQueryErrors })
|
|
40709
|
+
)
|
|
40484
40710
|
).pipe(
|
|
40485
40711
|
Command_exports.withDescription("Build and deploy. Without a login this creates a temporary unclaimed app."),
|
|
40486
|
-
Command_exports.withExamples([
|
|
40712
|
+
Command_exports.withExamples([
|
|
40713
|
+
{ command: "eraspace deploy --delete-table drafts=12", description: "Deploy a schema without drafts, deleting its 12 rows" },
|
|
40714
|
+
{ command: "eraspace deploy --fail-on-query-errors", description: "Deploy only if no live query starts throwing on the new code" }
|
|
40715
|
+
])
|
|
40487
40716
|
);
|
|
40488
40717
|
var devCommand = Command_exports.make("dev", deployFlags, (input) => Effect_exports.flatMap(config, (c2) => dev(c2, deployOptions(input)))).pipe(
|
|
40489
40718
|
Command_exports.withDescription("Deploy, then redeploy whenever server/, client/, shared/ or .env.eraspace.server change")
|
|
@@ -40491,14 +40720,38 @@ var devCommand = Command_exports.make("dev", deployFlags, (input) => Effect_expo
|
|
|
40491
40720
|
var callCommand = Command_exports.make(
|
|
40492
40721
|
"call",
|
|
40493
40722
|
{
|
|
40494
|
-
fn: Argument_exports.String("fn").pipe(Argument_exports.withDescription("Query or
|
|
40723
|
+
fn: Argument_exports.String("fn").pipe(Argument_exports.withDescription("Query, mutation or action name")),
|
|
40495
40724
|
args: Argument_exports.String("json").pipe(Argument_exports.withDescription("Arguments, each one a JSON value"), Argument_exports.variadic())
|
|
40496
40725
|
},
|
|
40497
|
-
({ fn: fn3, args: args2 }) => Effect_exports.flatMap(config, (c2) =>
|
|
40726
|
+
({ fn: fn3, args: args2 }) => Effect_exports.flatMap(config, (c2) => call2(c2, fn3, args2))
|
|
40498
40727
|
).pipe(
|
|
40499
40728
|
Command_exports.withDescription("Call a handler with positional JSON arguments"),
|
|
40500
40729
|
Command_exports.withExamples([{ command: `eraspace call messages '"general"'`, description: "Strings are JSON too, so quote them" }])
|
|
40501
40730
|
);
|
|
40731
|
+
var profileCommand = Command_exports.make(
|
|
40732
|
+
"profile",
|
|
40733
|
+
{
|
|
40734
|
+
app: optionalArg("app", "App name or id (default: this checkout's app)"),
|
|
40735
|
+
seconds: Flag_exports.Int("seconds").pipe(Flag_exports.filter((n) => n >= 1 && n <= 60, (n) => `--seconds must be between 1 and 60, got ${n}`), Flag_exports.withDefault(10), Flag_exports.withDescription("How long to sample")),
|
|
40736
|
+
out: optionalString("out", "Where to write the .cpuprofile (default: <app>-<time>.cpuprofile)")
|
|
40737
|
+
},
|
|
40738
|
+
({ app, seconds: seconds2, out }) => Effect_exports.flatMap(config, (c2) => profile(c2, value3(app), seconds2, value3(out)))
|
|
40739
|
+
).pipe(
|
|
40740
|
+
Command_exports.withDescription("Sample the app's server CPU time and write a .cpuprofile that opens in Chrome DevTools against the TypeScript sources"),
|
|
40741
|
+
Command_exports.withExamples([{ command: "eraspace profile my-app --seconds 10", description: "Profile while you exercise the app" }])
|
|
40742
|
+
);
|
|
40743
|
+
var explainCommand = Command_exports.make(
|
|
40744
|
+
"explain",
|
|
40745
|
+
{
|
|
40746
|
+
fn: Argument_exports.String("fn").pipe(Argument_exports.withDescription("Query name")),
|
|
40747
|
+
args: Argument_exports.String("json").pipe(Argument_exports.withDescription("Arguments, each one a JSON value"), Argument_exports.variadic()),
|
|
40748
|
+
json: Flag_exports.Boolean("json").pipe(Flag_exports.withDefault(false), Flag_exports.withDescription("Print the full report as JSON"))
|
|
40749
|
+
},
|
|
40750
|
+
({ fn: fn3, args: args2, json: json2 }) => Effect_exports.flatMap(config, (c2) => explain(c2, fn3, args2, json2))
|
|
40751
|
+
).pipe(
|
|
40752
|
+
Command_exports.withDescription("Run a query once and suggest indexes for rows it filters in JavaScript"),
|
|
40753
|
+
Command_exports.withExamples([{ command: `eraspace explain todosByStatus '"done"'`, description: "Strings are JSON too, so quote them" }])
|
|
40754
|
+
);
|
|
40502
40755
|
var logsCommand = Command_exports.make(
|
|
40503
40756
|
"logs",
|
|
40504
40757
|
{
|
|
@@ -40543,15 +40796,40 @@ var inspectionCommand = Command_exports.make(
|
|
|
40543
40796
|
},
|
|
40544
40797
|
({ visibility, app }) => Effect_exports.flatMap(config, (c2) => inspection(c2, visibility, value3(app)))
|
|
40545
40798
|
).pipe(Command_exports.withDescription("Open or close inspection and logs to everyone"));
|
|
40546
|
-
var
|
|
40547
|
-
var lifecycleCommand = (action, description) => Command_exports.make(
|
|
40548
|
-
|
|
40799
|
+
var lifecycleApp = optionalArg("app", "App name or id (default: this checkout's app)");
|
|
40800
|
+
var lifecycleCommand = (action, description) => Command_exports.make(action, { app: lifecycleApp }, ({ app }) => Effect_exports.flatMap(config, (c2) => lifecycle(c2, action, value3(app), false))).pipe(
|
|
40801
|
+
Command_exports.withDescription(description)
|
|
40802
|
+
);
|
|
40803
|
+
var changesCommand = Command_exports.make(
|
|
40804
|
+
"changes",
|
|
40549
40805
|
{
|
|
40550
|
-
|
|
40551
|
-
|
|
40806
|
+
since: Flag_exports.Int("since").pipe(Flag_exports.filter((n) => n >= 0, (n) => `--since must be a commit number, got ${n}`), Flag_exports.withDefault(0), Flag_exports.withDescription("Print changes committed after this commit")),
|
|
40807
|
+
limit: Flag_exports.Int("limit").pipe(Flag_exports.filter((n) => n >= 1 && n <= 1e4, (n) => `--limit must be between 1 and 10000, got ${n}`), Flag_exports.withDefault(1e3), Flag_exports.withDescription("Rows to print at most (whole commits)"))
|
|
40808
|
+
},
|
|
40809
|
+
({ since, limit }) => Effect_exports.flatMap(config, (c2) => changes2(c2, since, limit))
|
|
40810
|
+
).pipe(
|
|
40811
|
+
Command_exports.withDescription("Print recent committed row changes as NDJSON (the change log keeps 24 hours by default)"),
|
|
40812
|
+
Command_exports.withExamples([{ command: "eraspace changes --since 120 | jq .", description: "Changes committed after commit 120" }])
|
|
40813
|
+
);
|
|
40814
|
+
var undoCommand = Command_exports.make(
|
|
40815
|
+
"undo",
|
|
40816
|
+
{
|
|
40817
|
+
to: Argument_exports.Int("commit").pipe(Argument_exports.withDescription("Commit number to restore rows to")),
|
|
40818
|
+
yes: Flag_exports.Boolean("yes").pipe(Flag_exports.withAlias("y"), Flag_exports.withDefault(false), Flag_exports.withDescription("Confirm the undo"))
|
|
40819
|
+
},
|
|
40820
|
+
({ to, yes }) => Effect_exports.flatMap(config, (c2) => undo(c2, to, yes))
|
|
40821
|
+
).pipe(
|
|
40822
|
+
Command_exports.withDescription("Put every row changed after a commit back as it was; needs --yes. The undo is a commit too, so it can be undone"),
|
|
40823
|
+
Command_exports.withExamples([{ command: "eraspace undo 120 --yes", description: "Revert everything committed after commit 120" }])
|
|
40824
|
+
);
|
|
40825
|
+
var terminateCommand = Command_exports.make(
|
|
40826
|
+
"terminate",
|
|
40827
|
+
{
|
|
40828
|
+
app: lifecycleApp,
|
|
40829
|
+
yes: Flag_exports.Boolean("yes").pipe(Flag_exports.withAlias("y"), Flag_exports.withDefault(false), Flag_exports.withDescription("Confirm that the app stops permanently"))
|
|
40552
40830
|
},
|
|
40553
|
-
({ app, yes }) => Effect_exports.flatMap(config, (c2) => lifecycle(c2,
|
|
40554
|
-
).pipe(Command_exports.withDescription(
|
|
40831
|
+
({ app, yes }) => Effect_exports.flatMap(config, (c2) => lifecycle(c2, "terminate", value3(app), yes))
|
|
40832
|
+
).pipe(Command_exports.withDescription("Stop permanently (data kept, no more deploys); needs --yes"));
|
|
40555
40833
|
var tokenCommand = Command_exports.make("token").pipe(
|
|
40556
40834
|
Command_exports.withDescription("Create, list and revoke API tokens"),
|
|
40557
40835
|
Command_exports.withSubcommands([
|
|
@@ -40585,6 +40863,8 @@ var command = eraspace.pipe(
|
|
|
40585
40863
|
deployCommand,
|
|
40586
40864
|
devCommand,
|
|
40587
40865
|
callCommand,
|
|
40866
|
+
explainCommand,
|
|
40867
|
+
profileCommand,
|
|
40588
40868
|
logsCommand,
|
|
40589
40869
|
inspectCommand,
|
|
40590
40870
|
authCommand,
|
|
@@ -40594,7 +40874,9 @@ var command = eraspace.pipe(
|
|
|
40594
40874
|
inspectionCommand,
|
|
40595
40875
|
lifecycleCommand("archive", "Stop serving and keep the data"),
|
|
40596
40876
|
lifecycleCommand("restore", "Serve an archived app again"),
|
|
40597
|
-
|
|
40877
|
+
terminateCommand,
|
|
40878
|
+
changesCommand,
|
|
40879
|
+
undoCommand,
|
|
40598
40880
|
tokenCommand,
|
|
40599
40881
|
...hidden
|
|
40600
40882
|
])
|