ignotum 0.0.7 → 0.0.9
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 +89 -101
- package/dist/cli/bin.mjs +1119 -195
- package/dist/cli/bin.mjs.map +1 -1
- package/dist/runtime/{api-DtX8qPrq.js → api-DzcR7spt.js} +36 -13
- package/dist/runtime/api-DzcR7spt.js.map +1 -0
- package/dist/runtime/{api-Dp4J-xt-.d.ts → api-jCl8Hzry.d.ts} +7 -9
- package/dist/runtime/client.d.ts +12 -5
- package/dist/runtime/client.js +285 -60
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/{descriptor-t6BOEGw9-C1rwYIlx.js → descriptor-C5VA9qRl-BKbdenuU.js} +38 -7
- package/dist/runtime/descriptor-C5VA9qRl-BKbdenuU.js.map +1 -0
- package/dist/runtime/file-C1abuMgd.js +173 -0
- package/dist/runtime/file-C1abuMgd.js.map +1 -0
- package/dist/runtime/{id-Btwac71X-DhnKYsjY.d.ts → id-Cs82tq9Q-Caqfx54f.d.ts} +51 -5
- package/dist/runtime/{index-B5KSOjGN.d.ts → index-D6VLTbDB.d.ts} +40 -21
- package/dist/runtime/internal/api.d.ts +2 -2
- package/dist/runtime/internal/api.js +1 -1
- package/dist/runtime/internal/host.d.ts +8 -7
- package/dist/runtime/internal/host.js +21 -10
- package/dist/runtime/internal/host.js.map +1 -1
- package/dist/runtime/internal/server.d.ts +1 -1
- package/dist/runtime/internal/server.js +1 -1
- package/dist/runtime/internal/types.d.ts +1 -1
- package/dist/runtime/internal/types.js +1 -1
- package/dist/runtime/{pagination-B1BzNkh8-BUSTbeSg.d.ts → pagination-Bt3l7QaC-D_zI5zsu.d.ts} +8 -4
- package/dist/runtime/pagination-DcIkTOFs.d.ts +1 -0
- package/dist/runtime/{schema-D9RmboaS.js → schema-B6PK_ZwV.js} +17 -3
- package/dist/runtime/schema-B6PK_ZwV.js.map +1 -0
- package/dist/runtime/server.d.ts +3 -3
- package/dist/runtime/server.js +2 -2
- package/dist/runtime/server.js.map +1 -1
- package/dist/runtime/sync-bMQq9tXx.d.ts +8 -0
- package/package.json +7 -5
- package/src/cli/agent-files.ts +52 -13
- package/src/cli/app-configuration.ts +4 -1
- package/src/cli/auth-client.ts +286 -0
- package/src/cli/build/server.ts +83 -6
- package/src/cli/command.ts +65 -2
- package/src/cli/control-client.ts +19 -6
- package/src/cli/new-app.ts +16 -0
- package/src/client/errors.ts +7 -10
- package/src/client/files.ts +153 -0
- package/src/client/hooks.ts +2 -15
- package/src/client/index.ts +7 -0
- package/src/client/sync.ts +158 -30
- package/src/dev-runtime/database.ts +69 -57
- package/src/dev-runtime/files.ts +337 -0
- package/src/dev-runtime/functions.ts +14 -6
- package/src/dev-runtime/migrations.ts +14 -0
- package/src/dev-runtime/sync.ts +134 -22
- package/src/internal/api.ts +16 -1
- package/src/server/index.ts +8 -1
- package/dist/runtime/api-DtX8qPrq.js.map +0 -1
- package/dist/runtime/descriptor-t6BOEGw9-C1rwYIlx.js.map +0 -1
- package/dist/runtime/id-D570vudg.js +0 -26
- package/dist/runtime/id-D570vudg.js.map +0 -1
- package/dist/runtime/pagination-BKPko9Hm.d.ts +0 -1
- package/dist/runtime/schema-D9RmboaS.js.map +0 -1
package/dist/runtime/client.js
CHANGED
|
@@ -1,12 +1,109 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
import {
|
|
3
|
-
import { a as
|
|
1
|
+
import { C as RuntimeRequestNonce, T as TableId, _ as AppId, a as RuntimeFileMetadata, b as IdAlphabet, c as fileFormats, d as fileLimits, f as fileMimeTypes, h as makeFileValue, l as fileGrantUrlOf, m as isFileValue, o as RuntimeFileOccurrence, p as grantFileValue, r as FileId, u as fileIdOf, v as DeploymentId, w as SubscriptionId, x as InvocationId, y as GeneratedId } from "./file-C1abuMgd.js";
|
|
2
|
+
import { b as decodeTransportValue, c as upgrade, d as Result$1, h as pending, m as inspectResult, o as PaginationPageSize, p as failureFromWire, s as initial, t as ValueDescriptor, x as encodeTransportObject } from "./descriptor-C5VA9qRl-BKbdenuU.js";
|
|
3
|
+
import { a as ErrorCode, c as ServerMessageJson, d as WireSuccess, f as AppStateRevision, i as DeploymentCloseCode, l as WireFailure, m as InvocationKey, n as functionPathOf, o as FunctionAddress, p as DeploymentGeneration, r as ClientMessageJson, s as Operation, u as WireResult } from "./api-DzcR7spt.js";
|
|
4
4
|
import { Array as Array$1, Cause, Context, Deferred, Duration, Effect, ErrorReporter, Fiber, HashMap, Layer, ManagedRuntime, Predicate, Schedule, Schema, String } from "effect";
|
|
5
|
+
import { customAlphabet } from "nanoid";
|
|
5
6
|
import { useCallback, useCallback as useCallback$1, useContext, useDebugValue, useDebugValue as useDebugValue$1, useEffect, useEffect as useEffect$1, useErrorBoundary, useId, useImperativeHandle, useLayoutEffect, useMemo, useMemo as useMemo$1, useReducer, useRef, useState, useState as useState$1 } from "preact/hooks";
|
|
6
7
|
import * as Socket from "effect/unstable/socket/Socket";
|
|
7
8
|
import * as BrowserCrypto from "@effect/platform-browser/BrowserCrypto";
|
|
8
|
-
import { customAlphabet } from "nanoid";
|
|
9
9
|
import { Component, Fragment, cloneElement, createContext, createElement, createRef, h, isValidElement, toChildArray } from "preact";
|
|
10
|
+
//#region ../shared/dist/id.js
|
|
11
|
+
const decodeGenerated = (definition, payload) => Schema.decodeSync(definition)(definition.idPrefix === void 0 ? payload : `${definition.idPrefix}_${payload}`);
|
|
12
|
+
var IdGenerator = class IdGenerator extends Context.Service()("@ignotum/shared/id/IdGenerator") {
|
|
13
|
+
static layer = Layer.sync(IdGenerator, () => {
|
|
14
|
+
const generatePayload = customAlphabet(IdAlphabet, 24);
|
|
15
|
+
return IdGenerator.of({ generate: (definition) => Effect.sync(() => decodeGenerated(definition, generatePayload())) });
|
|
16
|
+
});
|
|
17
|
+
static deterministic = (startAt = 1) => Layer.sync(IdGenerator, () => {
|
|
18
|
+
const counters = /* @__PURE__ */ new Map();
|
|
19
|
+
return IdGenerator.of({ generate: (definition) => Effect.sync(() => {
|
|
20
|
+
const counter = (counters.get(definition.idPrefix) ?? startAt - 1) + 1;
|
|
21
|
+
counters.set(definition.idPrefix, counter);
|
|
22
|
+
return decodeGenerated(definition, counter.toString(36).padStart(24, "0"));
|
|
23
|
+
}) });
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/client/files.ts
|
|
28
|
+
const Files = { url: (file) => {
|
|
29
|
+
const url = fileGrantUrlOf(file);
|
|
30
|
+
if (url === void 0) throw new Error("This FileValue has no active query grant.");
|
|
31
|
+
return url;
|
|
32
|
+
} };
|
|
33
|
+
const formatByMime = {};
|
|
34
|
+
for (const format of fileFormats) formatByMime[fileMimeTypes[format]] = format;
|
|
35
|
+
const collectNativeFiles = (value, files) => {
|
|
36
|
+
if (value instanceof File) {
|
|
37
|
+
files.push(value);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (isFileValue(value) || Predicate.isDate(value)) return;
|
|
41
|
+
if (globalThis.Array.isArray(value)) {
|
|
42
|
+
for (const child of value) collectNativeFiles(child, files);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (!Predicate.isObject(value)) return;
|
|
46
|
+
for (const child of Object.values(value)) collectNativeFiles(child, files);
|
|
47
|
+
};
|
|
48
|
+
const replaceNativeFiles = (value, replacements) => {
|
|
49
|
+
if (value instanceof File) return replacements.get(value);
|
|
50
|
+
if (isFileValue(value) || Predicate.isDate(value)) return value;
|
|
51
|
+
if (globalThis.Array.isArray(value)) return value.map((child) => replaceNativeFiles(child, replacements));
|
|
52
|
+
if (!Predicate.isObject(value)) return value;
|
|
53
|
+
return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, replaceNativeFiles(child, replacements)]));
|
|
54
|
+
};
|
|
55
|
+
const prepareMutationArguments = Effect.fn("SyncClient.prepareMutationArguments")(function* (input) {
|
|
56
|
+
const ids = yield* IdGenerator;
|
|
57
|
+
const native = [];
|
|
58
|
+
collectNativeFiles(input, native);
|
|
59
|
+
const unique = new Set(native);
|
|
60
|
+
if (unique.size > fileLimits.filesPerMutation) throw new Error(`A mutation may upload at most ${fileLimits.filesPerMutation} files.`);
|
|
61
|
+
if ([...unique].reduce((total, file) => total + file.size, 0) > fileLimits.mutationBytes) throw new Error(`Mutation uploads may total at most ${fileLimits.mutationBytes} bytes.`);
|
|
62
|
+
const replacements = /* @__PURE__ */ new Map();
|
|
63
|
+
const nativeFiles = /* @__PURE__ */ new Map();
|
|
64
|
+
for (const file of unique) {
|
|
65
|
+
const format = formatByMime[file.type.toLowerCase()];
|
|
66
|
+
if (format === void 0) throw new Error(`File '${file.name}' has unsupported media type '${file.type || "unknown"}'.`);
|
|
67
|
+
if (file.size === 0 || file.size > fileLimits.fileBytes) throw new Error(`File '${file.name}' must be between 1 and ${fileLimits.fileBytes} bytes.`);
|
|
68
|
+
if (new TextEncoder().encode(file.name).byteLength > fileLimits.filenameBytes) throw new Error(`File '${file.name}' has a filename that is too long.`);
|
|
69
|
+
const id = yield* ids.generate(FileId);
|
|
70
|
+
replacements.set(file, makeFileValue(id, {
|
|
71
|
+
format,
|
|
72
|
+
name: file.name,
|
|
73
|
+
size: file.size
|
|
74
|
+
}));
|
|
75
|
+
nativeFiles.set(id, file);
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
value: replaceNativeFiles(input, replacements),
|
|
79
|
+
nativeFiles,
|
|
80
|
+
fileIds: Array.from(nativeFiles.keys())
|
|
81
|
+
};
|
|
82
|
+
});
|
|
83
|
+
const applyFileGrants = (value, grants) => {
|
|
84
|
+
const byId = /* @__PURE__ */ new Map();
|
|
85
|
+
for (const grant of grants) {
|
|
86
|
+
if (byId.has(grant.id)) throw new Error("A query file grant ID is duplicated.");
|
|
87
|
+
byId.set(grant.id, grant.url);
|
|
88
|
+
}
|
|
89
|
+
const matched = /* @__PURE__ */ new Set();
|
|
90
|
+
const visit = (current) => {
|
|
91
|
+
if (isFileValue(current)) {
|
|
92
|
+
const id = fileIdOf(current);
|
|
93
|
+
const url = byId.get(id);
|
|
94
|
+
if (url === void 0) return current;
|
|
95
|
+
matched.add(id);
|
|
96
|
+
return grantFileValue(current, url);
|
|
97
|
+
}
|
|
98
|
+
if (globalThis.Array.isArray(current)) return current.map(visit);
|
|
99
|
+
if (!Predicate.isObject(current) || Predicate.isDate(current)) return current;
|
|
100
|
+
return Object.fromEntries(Object.entries(current).map(([key, child]) => [key, visit(child)]));
|
|
101
|
+
};
|
|
102
|
+
const granted = visit(value);
|
|
103
|
+
if (matched.size !== byId.size) throw new Error("A query file grant has no result value.");
|
|
104
|
+
return granted;
|
|
105
|
+
};
|
|
106
|
+
//#endregion
|
|
10
107
|
//#region ../contracts/dist/json.js
|
|
11
108
|
const encodeScalar = (value) => Schema.decodeSync(Schema.String)(JSON.stringify(value));
|
|
12
109
|
const encodeCanonicalJson = (value) => {
|
|
@@ -37,8 +134,8 @@ var InvalidServerMessage = class extends Schema.TaggedError()("InvalidServerMess
|
|
|
37
134
|
cause: Schema.Defect(),
|
|
38
135
|
message: Schema.String
|
|
39
136
|
}) {};
|
|
40
|
-
var
|
|
41
|
-
code:
|
|
137
|
+
var ServerError = class extends Schema.TaggedError()("ServerError", {
|
|
138
|
+
code: ErrorCode,
|
|
42
139
|
message: Schema.String,
|
|
43
140
|
operation: Schema.optional(Operation)
|
|
44
141
|
}) {};
|
|
@@ -47,7 +144,7 @@ const ClientInfrastructureError = Schema.Union([
|
|
|
47
144
|
InvalidClientMessage,
|
|
48
145
|
InvalidMutationArguments,
|
|
49
146
|
InvalidServerMessage,
|
|
50
|
-
|
|
147
|
+
ServerError
|
|
51
148
|
]);
|
|
52
149
|
const browserErrorReporter = ErrorReporter.make(({ attributes, error }) => {
|
|
53
150
|
globalThis.console.error("Ignotum infrastructure error", error, attributes);
|
|
@@ -114,13 +211,41 @@ const RuntimeQueryResult = Schema.Struct({
|
|
|
114
211
|
type: Schema.Literal("Query"),
|
|
115
212
|
result: WireResult,
|
|
116
213
|
dependencies: DependencySet,
|
|
117
|
-
observedRevision: AppStateRevision
|
|
214
|
+
observedRevision: AppStateRevision,
|
|
215
|
+
files: Schema.optional(Schema.Array(RuntimeFileOccurrence))
|
|
216
|
+
});
|
|
217
|
+
const FileReferenceAdded = Schema.Struct({
|
|
218
|
+
type: Schema.Literal("AddReference"),
|
|
219
|
+
file: RuntimeFileMetadata,
|
|
220
|
+
tableId: TableId,
|
|
221
|
+
documentId: GeneratedId
|
|
222
|
+
});
|
|
223
|
+
const FileReferenceRemoved = Schema.Struct({
|
|
224
|
+
type: Schema.Literal("RemoveReference"),
|
|
225
|
+
fileId: FileId,
|
|
226
|
+
tableId: TableId,
|
|
227
|
+
documentId: GeneratedId
|
|
228
|
+
});
|
|
229
|
+
const FileReferenceEffect = Schema.Union([FileReferenceAdded, FileReferenceRemoved]);
|
|
230
|
+
const FileEffectBatch = Schema.Struct({
|
|
231
|
+
id: InvocationId,
|
|
232
|
+
committedRevision: AppStateRevision,
|
|
233
|
+
effects: Schema.Array(FileReferenceEffect)
|
|
234
|
+
});
|
|
235
|
+
Schema.Struct({ appId: AppId });
|
|
236
|
+
Schema.Struct({ batches: Schema.Array(FileEffectBatch) });
|
|
237
|
+
Schema.Struct({
|
|
238
|
+
appId: AppId,
|
|
239
|
+
invocationId: InvocationId,
|
|
240
|
+
acknowledgedAt: Schema.Int
|
|
118
241
|
});
|
|
242
|
+
Schema.Struct({ completed: Schema.Literal(true) });
|
|
119
243
|
const RuntimeMutationSuccess = Schema.Struct({
|
|
120
244
|
type: Schema.Literal("Mutation"),
|
|
121
245
|
result: WireSuccess,
|
|
122
246
|
invalidations: InvalidationSet,
|
|
123
|
-
committedRevision: AppStateRevision
|
|
247
|
+
committedRevision: AppStateRevision,
|
|
248
|
+
fileEffects: Schema.optional(FileEffectBatch)
|
|
124
249
|
});
|
|
125
250
|
const RuntimeMutationFailure = Schema.Struct({
|
|
126
251
|
type: Schema.Literal("Mutation"),
|
|
@@ -143,7 +268,8 @@ const QueryInvocation = Schema.Struct({
|
|
|
143
268
|
const MutationInvocation = Schema.Struct({
|
|
144
269
|
...InvocationBase,
|
|
145
270
|
type: Schema.Literal("Mutation"),
|
|
146
|
-
invocationId: InvocationId
|
|
271
|
+
invocationId: InvocationId,
|
|
272
|
+
files: Schema.optional(Schema.Array(RuntimeFileOccurrence))
|
|
147
273
|
});
|
|
148
274
|
Schema.Union([QueryInvocation, MutationInvocation]);
|
|
149
275
|
Schema.Struct({
|
|
@@ -182,23 +308,6 @@ Schema.Union([
|
|
|
182
308
|
RuntimeInvocationUnavailable
|
|
183
309
|
]);
|
|
184
310
|
//#endregion
|
|
185
|
-
//#region ../shared/dist/id.js
|
|
186
|
-
const decodeGenerated = (definition, payload) => Schema.decodeSync(definition)(definition.idPrefix === void 0 ? payload : `${definition.idPrefix}_${payload}`);
|
|
187
|
-
var IdGenerator = class IdGenerator extends Context.Service()("@ignotum/shared/id/IdGenerator") {
|
|
188
|
-
static layer = Layer.sync(IdGenerator, () => {
|
|
189
|
-
const generatePayload = customAlphabet(IdAlphabet, 24);
|
|
190
|
-
return IdGenerator.of({ generate: (definition) => Effect.sync(() => decodeGenerated(definition, generatePayload())) });
|
|
191
|
-
});
|
|
192
|
-
static deterministic = (startAt = 1) => Layer.sync(IdGenerator, () => {
|
|
193
|
-
const counters = /* @__PURE__ */ new Map();
|
|
194
|
-
return IdGenerator.of({ generate: (definition) => Effect.sync(() => {
|
|
195
|
-
const counter = (counters.get(definition.idPrefix) ?? startAt - 1) + 1;
|
|
196
|
-
counters.set(definition.idPrefix, counter);
|
|
197
|
-
return decodeGenerated(definition, counter.toString(36).padStart(24, "0"));
|
|
198
|
-
}) });
|
|
199
|
-
});
|
|
200
|
-
};
|
|
201
|
-
//#endregion
|
|
202
311
|
//#region ../contracts/dist/runtime/functions.js
|
|
203
312
|
const FunctionKind = Schema.Literals(["Mutation", "Query"]);
|
|
204
313
|
Schema.TaggedError()("UnknownFunction", {
|
|
@@ -253,24 +362,27 @@ const ClientRoute = Schema.Struct({
|
|
|
253
362
|
pathname: ClientPath,
|
|
254
363
|
artifact: ArtifactReference
|
|
255
364
|
});
|
|
256
|
-
Schema.Struct({
|
|
365
|
+
const DeploymentInventoryV1 = Schema.Struct({
|
|
257
366
|
formatVersion: Schema.Literal(1),
|
|
258
367
|
files: Schema.Array(ArtifactFile)
|
|
259
368
|
});
|
|
260
|
-
|
|
369
|
+
initial(DeploymentInventoryV1);
|
|
370
|
+
const ClientManifestV1 = Schema.Struct({
|
|
261
371
|
formatVersion: Schema.Literal(1),
|
|
262
372
|
shell: ArtifactReference,
|
|
263
373
|
routes: Schema.Array(ClientRoute)
|
|
264
374
|
});
|
|
375
|
+
initial(ClientManifestV1);
|
|
265
376
|
const ClientRoutingRoute = Schema.Struct({
|
|
266
377
|
pathname: ClientPath,
|
|
267
378
|
artifact: ArtifactPath
|
|
268
379
|
});
|
|
269
|
-
Schema.Struct({
|
|
380
|
+
const ClientRoutingV1 = Schema.Struct({
|
|
270
381
|
formatVersion: Schema.Literal(1),
|
|
271
382
|
shell: ArtifactPath,
|
|
272
383
|
routes: Schema.Array(ClientRoutingRoute)
|
|
273
384
|
});
|
|
385
|
+
initial(ClientRoutingV1);
|
|
274
386
|
const SchemaSnapshotField = Schema.Struct({
|
|
275
387
|
name: Schema.String,
|
|
276
388
|
value: ValueDescriptor
|
|
@@ -279,26 +391,60 @@ const SchemaSnapshotIndex = Schema.Struct({
|
|
|
279
391
|
name: Schema.String,
|
|
280
392
|
fields: Schema.Array(Schema.String)
|
|
281
393
|
});
|
|
394
|
+
const SchemaSnapshotTableV1 = Schema.Struct({
|
|
395
|
+
name: Schema.String,
|
|
396
|
+
fields: Schema.Array(SchemaSnapshotField)
|
|
397
|
+
});
|
|
398
|
+
const SchemaSnapshotV1 = Schema.Struct({
|
|
399
|
+
formatVersion: Schema.Literal(1),
|
|
400
|
+
tables: Schema.Array(SchemaSnapshotTableV1)
|
|
401
|
+
});
|
|
282
402
|
const SchemaSnapshotTable = Schema.Struct({
|
|
283
403
|
name: Schema.String,
|
|
284
404
|
fields: Schema.Array(SchemaSnapshotField),
|
|
285
405
|
indexes: Schema.Array(SchemaSnapshotIndex)
|
|
286
406
|
});
|
|
287
|
-
Schema.Struct({
|
|
407
|
+
const SchemaSnapshotV2 = Schema.Struct({
|
|
288
408
|
formatVersion: Schema.Literal(2),
|
|
289
409
|
tables: Schema.Array(SchemaSnapshotTable)
|
|
290
410
|
});
|
|
411
|
+
upgrade(initial(SchemaSnapshotV1), SchemaSnapshotV2, (snapshot) => ({
|
|
412
|
+
formatVersion: 2,
|
|
413
|
+
tables: snapshot.tables.map((table) => ({
|
|
414
|
+
...table,
|
|
415
|
+
indexes: []
|
|
416
|
+
}))
|
|
417
|
+
}));
|
|
418
|
+
const ServerFunctionArtifactV1 = Schema.Struct({
|
|
419
|
+
address: FunctionAddress,
|
|
420
|
+
kind: FunctionKind,
|
|
421
|
+
bundle: ArtifactReference,
|
|
422
|
+
sourceMap: ArtifactReference
|
|
423
|
+
});
|
|
291
424
|
const ServerFunctionArtifact = Schema.Struct({
|
|
292
425
|
address: FunctionAddress,
|
|
293
426
|
kind: FunctionKind,
|
|
427
|
+
args: Schema.optional(ValueDescriptor),
|
|
428
|
+
returns: Schema.optional(ValueDescriptor),
|
|
429
|
+
errors: Schema.optional(ValueDescriptor),
|
|
294
430
|
bundle: ArtifactReference,
|
|
295
431
|
sourceMap: ArtifactReference
|
|
296
432
|
});
|
|
297
|
-
Schema.Struct({
|
|
433
|
+
const ServerBuildManifestV1 = Schema.Struct({
|
|
298
434
|
formatVersion: Schema.Literal(1),
|
|
299
435
|
schema: ArtifactReference,
|
|
436
|
+
functions: Schema.Array(ServerFunctionArtifactV1)
|
|
437
|
+
});
|
|
438
|
+
const ServerBuildManifestV2 = Schema.Struct({
|
|
439
|
+
formatVersion: Schema.Literal(2),
|
|
440
|
+
schema: ArtifactReference,
|
|
300
441
|
functions: Schema.Array(ServerFunctionArtifact)
|
|
301
442
|
});
|
|
443
|
+
upgrade(initial(ServerBuildManifestV1), ServerBuildManifestV2, (manifest) => ({
|
|
444
|
+
formatVersion: 2,
|
|
445
|
+
schema: manifest.schema,
|
|
446
|
+
functions: manifest.functions
|
|
447
|
+
}));
|
|
302
448
|
ArtifactPath.make("inventory.json");
|
|
303
449
|
ArtifactPath.make("client/manifest.json");
|
|
304
450
|
ArtifactPath.make("client/shell.html");
|
|
@@ -312,12 +458,16 @@ const runtimeInvocationPath = "/v1/invoke";
|
|
|
312
458
|
const runtimeRevisionPath = "/v1/revision";
|
|
313
459
|
const runtimeIndexPreparePath = "/v1/indexes/prepare";
|
|
314
460
|
const runtimeIndexCommitPath = "/v1/indexes/commit";
|
|
461
|
+
const runtimeFileEffectsPath = "/v1/files/effects";
|
|
462
|
+
const runtimeFileEffectsAcknowledgePath = "/v1/files/effects/acknowledge";
|
|
315
463
|
const appSyncPath = `/_ignotum/v1/sync`;
|
|
316
464
|
const RuntimeRequestPath = Schema.Literals([
|
|
317
465
|
runtimeInvocationPath,
|
|
318
466
|
runtimeRevisionPath,
|
|
319
467
|
runtimeIndexPreparePath,
|
|
320
|
-
runtimeIndexCommitPath
|
|
468
|
+
runtimeIndexCommitPath,
|
|
469
|
+
runtimeFileEffectsPath,
|
|
470
|
+
runtimeFileEffectsAcknowledgePath
|
|
321
471
|
]);
|
|
322
472
|
const RuntimeRequestTimestamp = Schema.FiniteFromString.pipe(Schema.check(Schema.isInt(), Schema.isGreaterThanOrEqualTo(0)), Schema.brand("ignotum/runtime/RequestTimestamp"));
|
|
323
473
|
const RuntimeRequestSignature = Sha256.pipe(Schema.brand("ignotum/runtime/RequestSignature"));
|
|
@@ -440,8 +590,8 @@ const makeQueryCache = (allocateId, sendLifecycleMessage) => {
|
|
|
440
590
|
}
|
|
441
591
|
};
|
|
442
592
|
};
|
|
443
|
-
const resultFromWire = Effect.fn("SyncClient.resultFromWire")((wire) => Effect.succeed(wire.type === "Success" ? Result$1.succeed(wire.value === void 0 ? void 0 : decodeTransportValue(wire.value, wire.dates ?? [])) : failureFromWire(wire.error, wire.dates)));
|
|
444
|
-
const shouldReloadForCloseCode = (code) => code ===
|
|
593
|
+
const resultFromWire = Effect.fn("SyncClient.resultFromWire")((wire, files = []) => Effect.succeed(wire.type === "Success" ? Result$1.succeed(wire.value === void 0 ? void 0 : applyFileGrants(decodeTransportValue(wire.value, wire.dates ?? []), files)) : failureFromWire(wire.error, wire.dates)));
|
|
594
|
+
const shouldReloadForCloseCode = (code) => code === DeploymentCloseCode;
|
|
445
595
|
const handshakesMatch = (first, next) => first.appId === next.appId && first.deploymentId === next.deploymentId && first.generation === next.generation;
|
|
446
596
|
const handshakeDecision = (remembered, acceptedOnConnection, next) => {
|
|
447
597
|
if (remembered !== void 0 && !handshakesMatch(remembered, next)) return "Reload";
|
|
@@ -484,14 +634,19 @@ var SyncClient = class SyncClient extends Context.Service()("ignotum/client/sync
|
|
|
484
634
|
const pendingInvocation = HashMap.getUnsafe(invocations, id);
|
|
485
635
|
if (pendingInvocation === void 0) return Effect.void;
|
|
486
636
|
invocations = HashMap.remove(invocations, id);
|
|
487
|
-
return reportClientError(error).pipe(Effect.andThen(Deferred.fail(pendingInvocation.deferred, error)), Effect.asVoid);
|
|
637
|
+
return reportClientError(error).pipe(Effect.andThen(Deferred.fail(pendingInvocation.prepared, error)), Effect.andThen(Deferred.fail(pendingInvocation.deferred, error)), Effect.asVoid);
|
|
488
638
|
};
|
|
489
639
|
const handleMessage = Effect.fn("SyncClient.handleMessage")(function* (message) {
|
|
490
640
|
switch (message.type) {
|
|
491
641
|
case "Snapshot":
|
|
492
642
|
if (queryCache.getById(message.id) === void 0) return;
|
|
493
|
-
yield* resultFromWire(message.result).pipe(Effect.tap((result) => Effect.sync(() => queryCache.setResult(message.id, result, message.revision))));
|
|
643
|
+
yield* resultFromWire(message.result, message.files ?? []).pipe(Effect.tap((result) => Effect.sync(() => queryCache.setResult(message.id, result, message.revision))));
|
|
494
644
|
return;
|
|
645
|
+
case "Preparation": {
|
|
646
|
+
const pendingInvocation = HashMap.getUnsafe(invocations, message.id);
|
|
647
|
+
if (pendingInvocation !== void 0) yield* Deferred.succeed(pendingInvocation.prepared, message.uploads);
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
495
650
|
case "Result": {
|
|
496
651
|
const pendingInvocation = HashMap.getUnsafe(invocations, message.id);
|
|
497
652
|
if (pendingInvocation === void 0) return;
|
|
@@ -499,11 +654,11 @@ var SyncClient = class SyncClient extends Context.Service()("ignotum/client/sync
|
|
|
499
654
|
yield* resultFromWire(message.result).pipe(Effect.flatMap((result) => Deferred.succeed(pendingInvocation.deferred, result)));
|
|
500
655
|
return;
|
|
501
656
|
}
|
|
502
|
-
case "
|
|
503
|
-
const error = message.operation === void 0 ?
|
|
657
|
+
case "Error": {
|
|
658
|
+
const error = message.operation === void 0 ? ServerError.make({
|
|
504
659
|
code: message.code,
|
|
505
660
|
message: message.message
|
|
506
|
-
}) :
|
|
661
|
+
}) : ServerError.make({
|
|
507
662
|
code: message.code,
|
|
508
663
|
message: message.message,
|
|
509
664
|
operation: message.operation
|
|
@@ -557,7 +712,7 @@ var SyncClient = class SyncClient extends Context.Service()("ignotum/client/sync
|
|
|
557
712
|
message: "The server returned an invalid sync message."
|
|
558
713
|
})));
|
|
559
714
|
if (message.type === "Handshake") return yield* acceptHandshake(message);
|
|
560
|
-
if (message.type === "
|
|
715
|
+
if (message.type === "Deployment") {
|
|
561
716
|
requestReload();
|
|
562
717
|
return;
|
|
563
718
|
}
|
|
@@ -581,24 +736,103 @@ var SyncClient = class SyncClient extends Context.Service()("ignotum/client/sync
|
|
|
581
736
|
});
|
|
582
737
|
const mutate = Effect.fn("SyncClient.mutate")(function* (functionAddress, args) {
|
|
583
738
|
const invocationId = yield* ids.generate(InvocationId);
|
|
739
|
+
const preparedArguments = yield* prepareMutationArguments(args).pipe(Effect.provideService(IdGenerator, ids), Effect.mapError((cause) => InvalidMutationArguments.make({
|
|
740
|
+
cause,
|
|
741
|
+
function: functionAddress,
|
|
742
|
+
message: `Mutation arguments for ${functionAddress} contain an unsupported file or value.`
|
|
743
|
+
})), Effect.tapError(reportClientError));
|
|
744
|
+
const jsonArgs = yield* Effect.try({
|
|
745
|
+
try: () => encodeTransportObject(preparedArguments.value),
|
|
746
|
+
catch: (cause) => InvalidMutationArguments.make({
|
|
747
|
+
cause,
|
|
748
|
+
function: functionAddress,
|
|
749
|
+
message: `Mutation arguments for ${functionAddress} contain an unsupported value.`
|
|
750
|
+
})
|
|
751
|
+
}).pipe(Effect.tapError(reportClientError));
|
|
584
752
|
const deferred = yield* Deferred.make();
|
|
585
|
-
const
|
|
753
|
+
const prepared = yield* Deferred.make();
|
|
754
|
+
const invokeMessage = {
|
|
586
755
|
type: "Invoke",
|
|
587
756
|
id: invocationId,
|
|
588
757
|
kind: "Mutation",
|
|
589
758
|
function: functionAddress,
|
|
590
|
-
args
|
|
759
|
+
args: jsonArgs
|
|
760
|
+
};
|
|
761
|
+
const message = preparedArguments.fileIds.length === 0 ? invokeMessage : {
|
|
762
|
+
type: "Prepare",
|
|
763
|
+
id: invocationId,
|
|
764
|
+
kind: "Mutation",
|
|
765
|
+
function: functionAddress,
|
|
766
|
+
args: jsonArgs,
|
|
767
|
+
files: preparedArguments.fileIds
|
|
591
768
|
};
|
|
592
769
|
invocations = HashMap.set(invocations, invocationId, {
|
|
593
770
|
deferred,
|
|
594
771
|
function: functionAddress,
|
|
595
|
-
message
|
|
772
|
+
message,
|
|
773
|
+
prepared
|
|
596
774
|
});
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
775
|
+
return yield* Effect.gen(function* () {
|
|
776
|
+
if (writer !== void 0) yield* sendWith(writer, message).pipe(Effect.catchTags({
|
|
777
|
+
ConnectionUnavailable: reportClientError,
|
|
778
|
+
InvalidClientMessage: (error) => rejectInvocation(invocationId, error)
|
|
779
|
+
}));
|
|
780
|
+
if (message.type === "Prepare") {
|
|
781
|
+
const uploads = yield* Deferred.await(prepared);
|
|
782
|
+
const expected = new Set(message.files);
|
|
783
|
+
const received = /* @__PURE__ */ new Set();
|
|
784
|
+
for (const upload of uploads) {
|
|
785
|
+
if (!expected.has(upload.id) || received.has(upload.id)) return yield* InvalidServerMessage.make({
|
|
786
|
+
cause: /* @__PURE__ */ new Error(`Unexpected prepared file '${upload.id}'.`),
|
|
787
|
+
message: "The server returned invalid application file preparation data."
|
|
788
|
+
});
|
|
789
|
+
received.add(upload.id);
|
|
790
|
+
const file = preparedArguments.nativeFiles.get(upload.id);
|
|
791
|
+
if (file === void 0) return yield* InvalidServerMessage.make({
|
|
792
|
+
cause: /* @__PURE__ */ new Error(`Missing native file '${upload.id}'.`),
|
|
793
|
+
message: "The server prepared an unknown application file."
|
|
794
|
+
});
|
|
795
|
+
if (upload.url === void 0) continue;
|
|
796
|
+
const uploadUrl = upload.url;
|
|
797
|
+
const response = yield* Effect.tryPromise({
|
|
798
|
+
try: () => fetch(uploadUrl, {
|
|
799
|
+
method: "PUT",
|
|
800
|
+
body: file,
|
|
801
|
+
headers: { "content-type": file.type }
|
|
802
|
+
}),
|
|
803
|
+
catch: (cause) => ConnectionUnavailable.make({
|
|
804
|
+
cause,
|
|
805
|
+
message: `File '${file.name}' could not be uploaded.`
|
|
806
|
+
})
|
|
807
|
+
});
|
|
808
|
+
if (!response.ok) {
|
|
809
|
+
const detail = yield* Effect.promise(() => response.text());
|
|
810
|
+
return yield* InvalidMutationArguments.make({
|
|
811
|
+
cause: new Error(detail),
|
|
812
|
+
function: functionAddress,
|
|
813
|
+
message: `File '${file.name}' was rejected by application storage.`
|
|
814
|
+
});
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
if (received.size !== expected.size) return yield* InvalidServerMessage.make({
|
|
818
|
+
cause: /* @__PURE__ */ new Error("The server omitted a prepared file."),
|
|
819
|
+
message: "The server returned incomplete application file preparation data."
|
|
820
|
+
});
|
|
821
|
+
const pendingInvocation = HashMap.getUnsafe(invocations, invocationId);
|
|
822
|
+
if (pendingInvocation === void 0) return yield* Deferred.await(deferred);
|
|
823
|
+
invocations = HashMap.set(invocations, invocationId, {
|
|
824
|
+
...pendingInvocation,
|
|
825
|
+
message: invokeMessage
|
|
826
|
+
});
|
|
827
|
+
if (writer !== void 0) yield* sendWith(writer, invokeMessage).pipe(Effect.catchTags({
|
|
828
|
+
ConnectionUnavailable: reportClientError,
|
|
829
|
+
InvalidClientMessage: (error) => rejectInvocation(invocationId, error)
|
|
830
|
+
}));
|
|
831
|
+
}
|
|
832
|
+
return yield* Deferred.await(deferred);
|
|
833
|
+
}).pipe(Effect.tapError(() => Effect.sync(() => {
|
|
834
|
+
invocations = HashMap.remove(invocations, invocationId);
|
|
835
|
+
})));
|
|
602
836
|
});
|
|
603
837
|
return SyncClient.of({
|
|
604
838
|
mutate,
|
|
@@ -801,16 +1035,7 @@ const useMutation = (reference) => useMemo$1(() => {
|
|
|
801
1035
|
const functionPath = functionPathOf(reference);
|
|
802
1036
|
const input = args === void 0 ? {} : args;
|
|
803
1037
|
return syncRuntime.runPromise(Effect.gen(function* () {
|
|
804
|
-
|
|
805
|
-
const jsonArgs = yield* Effect.try({
|
|
806
|
-
try: () => encodeTransportObject(input),
|
|
807
|
-
catch: (cause) => InvalidMutationArguments.make({
|
|
808
|
-
cause,
|
|
809
|
-
function: functionPath,
|
|
810
|
-
message: `Mutation arguments for ${functionPath} contain an unsupported value.`
|
|
811
|
-
})
|
|
812
|
-
}).pipe(Effect.tapError(reportClientError));
|
|
813
|
-
return yield* client.mutate(functionPath, jsonArgs);
|
|
1038
|
+
return yield* (yield* SyncClient).mutate(functionPath, input);
|
|
814
1039
|
}));
|
|
815
1040
|
};
|
|
816
1041
|
return mutate;
|
|
@@ -825,6 +1050,6 @@ const app = (definition) => {
|
|
|
825
1050
|
//#region src/client/index.ts
|
|
826
1051
|
const Result = { match: Result$1.match };
|
|
827
1052
|
//#endregion
|
|
828
|
-
export { Component, Fragment, Query, Result, app, cloneElement, createContext, createElement, createRef, h, isValidElement, toChildArray, useCallback, useContext, useDebugValue, useEffect, useErrorBoundary, useId, useImperativeHandle, useLayoutEffect, useMemo, useMutation, usePaginatedQuery, useQuery, useReducer, useRef, useState };
|
|
1053
|
+
export { Component, Files, Fragment, Query, Result, app, cloneElement, createContext, createElement, createRef, h, isValidElement, toChildArray, useCallback, useContext, useDebugValue, useEffect, useErrorBoundary, useId, useImperativeHandle, useLayoutEffect, useMemo, useMutation, usePaginatedQuery, useQuery, useReducer, useRef, useState };
|
|
829
1054
|
|
|
830
1055
|
//# sourceMappingURL=client.js.map
|