@gjermundgaraba/clankerbox-sdk 0.18.3 → 0.19.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/dist/{client-8af586hb.d.mts → client-BodRGKAX.d.mts} +347 -255
- package/dist/{client-DHNZ57xn.mjs → client-BwhQ_WUi.mjs} +148 -98
- package/dist/index.d.mts +8 -17
- package/dist/index.mjs +14 -46
- package/dist/node.d.mts +1 -1
- package/dist/node.mjs +1 -1
- package/package.json +10 -11
|
@@ -24,20 +24,31 @@ var NotFound = class extends Schema.TaggedError()("NotFound", {
|
|
|
24
24
|
message: Schema.String,
|
|
25
25
|
...located
|
|
26
26
|
}, { httpApiStatus: 404 }) {};
|
|
27
|
-
|
|
28
|
-
/** The name is taken (`exists`), or another action holds the resource (`busy`). */
|
|
27
|
+
/** The name is taken. */
|
|
29
28
|
var Conflict = class extends Schema.TaggedError()("Conflict", {
|
|
30
29
|
message: Schema.String,
|
|
31
|
-
kind: ConflictKind,
|
|
32
30
|
...located
|
|
33
31
|
}, { httpApiStatus: 409 }) {};
|
|
32
|
+
/**
|
|
33
|
+
* A later request on the machine replaced this one before the host got there: `by` is what that
|
|
34
|
+
* request asked for. The machine's own state says where it is now.
|
|
35
|
+
*/
|
|
36
|
+
var Superseded = class extends Schema.TaggedError()("Superseded", {
|
|
37
|
+
message: Schema.String,
|
|
38
|
+
...located,
|
|
39
|
+
by: Schema.Literals([
|
|
40
|
+
"running",
|
|
41
|
+
"stopped",
|
|
42
|
+
"deleted"
|
|
43
|
+
])
|
|
44
|
+
}, { httpApiStatus: 409 }) {};
|
|
34
45
|
/** No host offers `base`: the host a create names, or any in the client's list. */
|
|
35
46
|
var NotOffered = class extends Schema.TaggedError()("NotOffered", {
|
|
36
47
|
message: Schema.String,
|
|
37
48
|
...located,
|
|
38
49
|
base: Schema.String
|
|
39
50
|
}, { httpApiStatus: 412 }) {};
|
|
40
|
-
/** `machine`'
|
|
51
|
+
/** `machine` isn't made yet: its create or setup still runs, so it can't be copied or captured. */
|
|
41
52
|
var NotMade = class extends Schema.TaggedError()("NotMade", {
|
|
42
53
|
message: Schema.String,
|
|
43
54
|
...located,
|
|
@@ -49,12 +60,6 @@ var Missing = class extends Schema.TaggedError()("Missing", {
|
|
|
49
60
|
...located,
|
|
50
61
|
machine: Schema.String
|
|
51
62
|
}, { httpApiStatus: 412 }) {};
|
|
52
|
-
/** `checkpoint`'s capture failed, so nothing restores from it: it can only be deleted. */
|
|
53
|
-
var NotReady = class extends Schema.TaggedError()("NotReady", {
|
|
54
|
-
message: Schema.String,
|
|
55
|
-
...located,
|
|
56
|
-
checkpoint: Schema.String
|
|
57
|
-
}, { httpApiStatus: 412 }) {};
|
|
58
63
|
/** `checkpoint` holds RAM state saved under another runtime pin than the one the host runs. */
|
|
59
64
|
var PinMismatch = class extends Schema.TaggedError()("PinMismatch", {
|
|
60
65
|
message: Schema.String,
|
|
@@ -75,12 +80,13 @@ var Unsizable = class extends Schema.TaggedError()("Unsizable", {
|
|
|
75
80
|
}, { httpApiStatus: 422 }) {};
|
|
76
81
|
/**
|
|
77
82
|
* A guest script exited non-zero or ran past its timeout; the message says which, with its
|
|
78
|
-
* output's tail
|
|
83
|
+
* output's tail, and `script` names it: a failed `setup` deletes the machine, and a failed
|
|
84
|
+
* `preparation` runs again on the next start.
|
|
79
85
|
*/
|
|
80
86
|
var ScriptFailed = class extends Schema.TaggedError()("ScriptFailed", {
|
|
81
87
|
message: Schema.String,
|
|
82
88
|
...located,
|
|
83
|
-
script: Schema.
|
|
89
|
+
script: Schema.String
|
|
84
90
|
}, { httpApiStatus: 422 }) {};
|
|
85
91
|
/** The provider under the runtime refused the call for good, such as for its plan or API key. */
|
|
86
92
|
var Refused = class extends Schema.TaggedError()("Refused", {
|
|
@@ -110,10 +116,10 @@ const hostErrors = [
|
|
|
110
116
|
Invalid,
|
|
111
117
|
NotFound,
|
|
112
118
|
Conflict,
|
|
119
|
+
Superseded,
|
|
113
120
|
NotOffered,
|
|
114
121
|
NotMade,
|
|
115
122
|
Missing,
|
|
116
|
-
NotReady,
|
|
117
123
|
PinMismatch,
|
|
118
124
|
WrongState,
|
|
119
125
|
Unsizable,
|
|
@@ -126,22 +132,24 @@ const HostError = Schema.Union(hostErrors);
|
|
|
126
132
|
/**
|
|
127
133
|
* Each carries, where known: `host` and `action`, which the client sets; `id`, the resource the
|
|
128
134
|
* error is about, which a host sets on `NotFound` and `Conflict` and the client sets to the call's
|
|
129
|
-
* subject otherwise; and `made`, the resource a create, fork, restore or capture makes
|
|
130
|
-
*
|
|
135
|
+
* subject otherwise; and `made`, the resource a create, fork, restore or capture makes. The host
|
|
136
|
+
* deletes a machine whose copy or setup fails, again at each recheck while that delete fails, and
|
|
137
|
+
* keeps one whose preparation fails; a call whose answer was lost, `Unavailable`, may leave
|
|
138
|
+
* `made` behind unmade.
|
|
131
139
|
*/
|
|
132
140
|
const ClankerboxError = Schema.Union([...hostErrors, Unavailable]);
|
|
133
141
|
/**
|
|
134
|
-
* Whether the same call may succeed later: a
|
|
135
|
-
*
|
|
142
|
+
* Whether the same call may succeed later: a full host may free up, and a read that got no reply
|
|
143
|
+
* may get one.
|
|
136
144
|
*/
|
|
137
145
|
const retryable = (error) => Match.value(error).pipe(Match.tagsExhaustive({
|
|
138
146
|
Invalid: () => false,
|
|
139
147
|
NotFound: () => false,
|
|
140
|
-
Conflict: (
|
|
148
|
+
Conflict: () => false,
|
|
149
|
+
Superseded: () => false,
|
|
141
150
|
NotOffered: () => false,
|
|
142
151
|
NotMade: () => false,
|
|
143
152
|
Missing: () => false,
|
|
144
|
-
NotReady: () => false,
|
|
145
153
|
PinMismatch: () => false,
|
|
146
154
|
WrongState: () => false,
|
|
147
155
|
Unsizable: () => false,
|
|
@@ -196,31 +204,31 @@ const Runtime = Schema.Literals([
|
|
|
196
204
|
"boat"
|
|
197
205
|
]);
|
|
198
206
|
const Size = Schema.Int.check(Schema.isGreaterThan(0));
|
|
199
|
-
/**
|
|
200
|
-
const
|
|
201
|
-
"createMachine",
|
|
202
|
-
"startMachine",
|
|
203
|
-
"stopMachine",
|
|
204
|
-
"deleteMachine",
|
|
205
|
-
"forkMachine",
|
|
206
|
-
"restoreMachine",
|
|
207
|
-
"captureCheckpoint",
|
|
208
|
-
"deleteCheckpoint"
|
|
209
|
-
]);
|
|
210
|
-
const ActionStatus = Schema.Literals([
|
|
207
|
+
/** What the operator asked a machine to be; the host keeps moving the machine toward it. */
|
|
208
|
+
const Desired = Schema.Literals([
|
|
211
209
|
"running",
|
|
210
|
+
"stopped",
|
|
211
|
+
"deleted"
|
|
212
|
+
]);
|
|
213
|
+
/**
|
|
214
|
+
* What the host is doing about a machine. A request waits for a rest: `settled`, at rest with what
|
|
215
|
+
* was asked; `failed`, after a step failed, until the next request; `lost`, one the runtime no
|
|
216
|
+
* longer has, which can only be deleted; and `waiting`, one the runtime can't read, which fails the
|
|
217
|
+
* request and is read again at the host's next recheck. `creating` copies the machine and runs its
|
|
218
|
+
* setup, and a machine whose create or setup fails is deleted. `starting` starts the machine, also
|
|
219
|
+
* when it runs already, and prepares it.
|
|
220
|
+
*/
|
|
221
|
+
const Phase = Schema.Literals([
|
|
222
|
+
"observing",
|
|
223
|
+
"waiting",
|
|
224
|
+
"creating",
|
|
225
|
+
"starting",
|
|
226
|
+
"stopping",
|
|
227
|
+
"deleting",
|
|
228
|
+
"settled",
|
|
212
229
|
"failed",
|
|
213
|
-
"
|
|
230
|
+
"lost"
|
|
214
231
|
]);
|
|
215
|
-
/** A resource's last action; the next action replaces it. */
|
|
216
|
-
const ActionRecord = Schema.Union([Schema.Struct({
|
|
217
|
-
name: ActionName,
|
|
218
|
-
status: Schema.Literals(["running", "done"])
|
|
219
|
-
}), Schema.Struct({
|
|
220
|
-
name: ActionName,
|
|
221
|
-
status: Schema.Literal("failed"),
|
|
222
|
-
error: HostError
|
|
223
|
-
})]);
|
|
224
232
|
const SshEndpoint = Schema.Struct({
|
|
225
233
|
host: Schema.String,
|
|
226
234
|
port: Schema.Int.check(Schema.isBetween({
|
|
@@ -233,10 +241,30 @@ const SshLogin = Schema.Struct({
|
|
|
233
241
|
...SshEndpoint.fields
|
|
234
242
|
});
|
|
235
243
|
/**
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
*
|
|
244
|
+
* A running machine's place on the tailnet, as the host last checked it: `joined` once
|
|
245
|
+
* `tailscaled` runs signed in, with the MagicDNS name Tailscale gave it, if any; `failed` with
|
|
246
|
+
* why; or `missing` when the guest has no `tailscaled`. Kept in the host's memory only: each start
|
|
247
|
+
* checks again, a joined machine is checked again every half hour or so, and a failed one sooner,
|
|
248
|
+
* waiting longer after each failure.
|
|
249
|
+
*/
|
|
250
|
+
const TailnetStatus = Schema.Union([
|
|
251
|
+
Schema.Struct({
|
|
252
|
+
state: Schema.Literal("joined"),
|
|
253
|
+
name: Schema.optionalKey(Schema.String)
|
|
254
|
+
}),
|
|
255
|
+
Schema.Struct({
|
|
256
|
+
state: Schema.Literal("failed"),
|
|
257
|
+
error: Schema.String
|
|
258
|
+
}),
|
|
259
|
+
Schema.Struct({ state: Schema.Literal("missing") })
|
|
260
|
+
]).annotate({ identifier: "TailnetStatus" });
|
|
261
|
+
/**
|
|
262
|
+
* `state` is what the runtime reports: `missing` when it doesn't have the machine, and `unknown`
|
|
263
|
+
* when it couldn't be read. `desired` is what the last request asked for, `phase` what the host is
|
|
264
|
+
* doing about it, and `error` why the last step failed, until the next request. `ssh` is only
|
|
265
|
+
* on a running machine whose runtime gives it an endpoint, and `hostKey`, `<type> <base64>`, once
|
|
266
|
+
* preparation has recorded it. `tailnet` is on a running machine of a host that joins its machines
|
|
267
|
+
* to a tailnet, once the host has checked it.
|
|
240
268
|
*/
|
|
241
269
|
const Machine = Schema.Struct({
|
|
242
270
|
id: Id,
|
|
@@ -253,14 +281,22 @@ const Machine = Schema.Struct({
|
|
|
253
281
|
"missing",
|
|
254
282
|
"unknown"
|
|
255
283
|
]),
|
|
256
|
-
|
|
257
|
-
|
|
284
|
+
desired: Desired,
|
|
285
|
+
phase: Phase,
|
|
286
|
+
error: Schema.optionalKey(HostError),
|
|
258
287
|
ssh: Schema.optionalKey(SshLogin),
|
|
259
|
-
hostKey: Schema.optionalKey(Schema.String)
|
|
288
|
+
hostKey: Schema.optionalKey(Schema.String),
|
|
289
|
+
tailnet: Schema.optionalKey(TailnetStatus)
|
|
260
290
|
}).annotate({ identifier: "Machine" });
|
|
261
|
-
/**
|
|
262
|
-
|
|
263
|
-
|
|
291
|
+
/**
|
|
292
|
+
* The state as people read it: `running` at rest, `running (failed)` where it is but not at rest,
|
|
293
|
+
* and `stopped, wants running (starting)` on the way.
|
|
294
|
+
*/
|
|
295
|
+
const stateLabel = ({ state, desired, phase }) => phase === "settled" ? state : state === desired ? `${state} (${phase})` : `${state}, wants ${desired} (${phase})`;
|
|
296
|
+
/**
|
|
297
|
+
* `kind` is `ram` (RAM and disks) on smolvm, and `disk` on Tart and boat. A checkpoint exists only
|
|
298
|
+
* once its capture is done, and never changes after.
|
|
299
|
+
*/
|
|
264
300
|
const Checkpoint = Schema.Struct({
|
|
265
301
|
id: Id,
|
|
266
302
|
createdAt: Schema.DateTimeUtcFromString,
|
|
@@ -270,11 +306,8 @@ const Checkpoint = Schema.Struct({
|
|
|
270
306
|
profile: Schema.optionalKey(Schema.String),
|
|
271
307
|
cpu: Size,
|
|
272
308
|
ramMib: Size,
|
|
273
|
-
diskGib: Size
|
|
274
|
-
action: ActionRecord
|
|
309
|
+
diskGib: Size
|
|
275
310
|
}).annotate({ identifier: "Checkpoint" });
|
|
276
|
-
/** A checkpoint restores once its capture is done; it never changes after. */
|
|
277
|
-
const isReady = (checkpoint) => checkpoint.action.status === "done";
|
|
278
311
|
/**
|
|
279
312
|
* `runtimeVersion` is boat's API version on boat. `captureFrom` is the state a machine must be in
|
|
280
313
|
* to be captured: Tart's is `stopped`.
|
|
@@ -336,6 +369,17 @@ const CreateRequest = Schema.Struct({
|
|
|
336
369
|
id: Id,
|
|
337
370
|
...specFields
|
|
338
371
|
});
|
|
372
|
+
/** A prebuild is the checkpoint `id` of a machine made from the spec, setup and all. */
|
|
373
|
+
const PrebuildRequest = Schema.Struct({
|
|
374
|
+
id: Id,
|
|
375
|
+
...specFields,
|
|
376
|
+
setup: Setup
|
|
377
|
+
});
|
|
378
|
+
/** `built` is false when the host already had the checkpoint. */
|
|
379
|
+
const Prebuilt = Schema.Struct({
|
|
380
|
+
checkpoint: Checkpoint,
|
|
381
|
+
built: Schema.Boolean
|
|
382
|
+
});
|
|
339
383
|
//#endregion
|
|
340
384
|
//#region src/api.ts
|
|
341
385
|
/** A host bounds its own reads of runtime state under it, so a list answers in time. */
|
|
@@ -359,20 +403,28 @@ const reading = [
|
|
|
359
403
|
NotFound,
|
|
360
404
|
Internal
|
|
361
405
|
];
|
|
362
|
-
const
|
|
406
|
+
const removing = [
|
|
363
407
|
Invalid,
|
|
364
408
|
NotFound,
|
|
365
|
-
Conflict,
|
|
366
409
|
Refused,
|
|
367
410
|
Internal
|
|
368
411
|
];
|
|
369
|
-
const
|
|
370
|
-
|
|
412
|
+
const converging = [
|
|
413
|
+
Invalid,
|
|
414
|
+
NotFound,
|
|
371
415
|
NotMade,
|
|
372
416
|
Missing,
|
|
373
417
|
WrongState,
|
|
374
|
-
|
|
418
|
+
PinMismatch,
|
|
419
|
+
Unsizable,
|
|
420
|
+
ScriptFailed,
|
|
421
|
+
Refused,
|
|
422
|
+
Capacity,
|
|
423
|
+
Superseded,
|
|
424
|
+
Internal
|
|
375
425
|
];
|
|
426
|
+
const making = [...converging, Conflict];
|
|
427
|
+
const creating = [...making, NotOffered];
|
|
376
428
|
const Http = ActionHttp.make([
|
|
377
429
|
Action.make("listMachines", {
|
|
378
430
|
...read,
|
|
@@ -389,62 +441,42 @@ const Http = ActionHttp.make([
|
|
|
389
441
|
}),
|
|
390
442
|
Action.make("createMachine", {
|
|
391
443
|
...write,
|
|
392
|
-
error:
|
|
393
|
-
|
|
394
|
-
Conflict,
|
|
395
|
-
NotOffered,
|
|
396
|
-
Unsizable,
|
|
397
|
-
ScriptFailed,
|
|
398
|
-
Refused,
|
|
399
|
-
Capacity,
|
|
400
|
-
Internal
|
|
401
|
-
],
|
|
402
|
-
description: "Create a machine from a base, run its setup once, and prepare it.",
|
|
444
|
+
error: creating,
|
|
445
|
+
description: "Create a machine from a base, run its setup once, and prepare it. A create or setup that fails deletes the machine, again at each recheck while that delete fails, and the error is the answer; a preparation that fails keeps it.",
|
|
403
446
|
input: CreateRequest,
|
|
404
447
|
success: Machine
|
|
405
448
|
}),
|
|
406
449
|
Action.make("startMachine", {
|
|
407
450
|
...write,
|
|
408
|
-
error:
|
|
409
|
-
description: "
|
|
451
|
+
error: converging,
|
|
452
|
+
description: "Ask for a machine to run, and wait until it does: start it and prepare it again, also when it runs already.",
|
|
410
453
|
input: ById,
|
|
411
454
|
success: Machine
|
|
412
455
|
}),
|
|
413
456
|
Action.make("stopMachine", {
|
|
414
457
|
...write,
|
|
415
|
-
error:
|
|
416
|
-
description: "
|
|
458
|
+
error: converging,
|
|
459
|
+
description: "Ask for a machine to stay stopped, and wait until it is: a power-off that keeps its disk and ends its processes. A start under way is cut short; a machine still being made is made first, and its create answers Superseded.",
|
|
417
460
|
input: ById,
|
|
418
461
|
success: Machine
|
|
419
462
|
}),
|
|
420
463
|
Action.make("deleteMachine", {
|
|
421
464
|
...write,
|
|
422
|
-
error:
|
|
423
|
-
description: "Delete a machine and everything native it owns.",
|
|
465
|
+
error: converging,
|
|
466
|
+
description: "Delete a machine and everything native it owns, whatever it is doing.",
|
|
424
467
|
input: ById
|
|
425
468
|
}),
|
|
426
469
|
Action.make("forkMachine", {
|
|
427
470
|
...write,
|
|
428
|
-
error:
|
|
429
|
-
|
|
430
|
-
Unsizable,
|
|
431
|
-
ScriptFailed
|
|
432
|
-
],
|
|
433
|
-
description: "Copy a machine to a new name on the same host.",
|
|
471
|
+
error: making,
|
|
472
|
+
description: "Copy a machine to a new name on the same host. A copy that fails deletes the new machine.",
|
|
434
473
|
input: FromMachine,
|
|
435
474
|
success: Machine
|
|
436
475
|
}),
|
|
437
476
|
Action.make("restoreMachine", {
|
|
438
477
|
...write,
|
|
439
|
-
error:
|
|
440
|
-
|
|
441
|
-
NotReady,
|
|
442
|
-
PinMismatch,
|
|
443
|
-
Unsizable,
|
|
444
|
-
ScriptFailed,
|
|
445
|
-
Capacity
|
|
446
|
-
],
|
|
447
|
-
description: "Create a machine on the checkpoint's host from that checkpoint.",
|
|
478
|
+
error: making,
|
|
479
|
+
description: "Create a machine on the checkpoint's host from that checkpoint. A restore that fails deletes the new machine.",
|
|
448
480
|
input: Schema.Struct({
|
|
449
481
|
checkpoint: Id,
|
|
450
482
|
name: Name
|
|
@@ -466,17 +498,34 @@ const Http = ActionHttp.make([
|
|
|
466
498
|
}),
|
|
467
499
|
Action.make("captureCheckpoint", {
|
|
468
500
|
...write,
|
|
469
|
-
error:
|
|
501
|
+
error: [
|
|
502
|
+
Invalid,
|
|
503
|
+
NotFound,
|
|
504
|
+
Conflict,
|
|
505
|
+
NotMade,
|
|
506
|
+
Missing,
|
|
507
|
+
WrongState,
|
|
508
|
+
Refused,
|
|
509
|
+
Capacity,
|
|
510
|
+
Internal
|
|
511
|
+
],
|
|
470
512
|
description: "Capture a checkpoint of a machine. Its kind follows the runtime: ram on smolvm, which captures only a running machine, and disk on Tart and boat.",
|
|
471
513
|
input: FromMachine,
|
|
472
514
|
success: Checkpoint
|
|
473
515
|
}),
|
|
474
516
|
Action.make("deleteCheckpoint", {
|
|
475
517
|
...write,
|
|
476
|
-
error:
|
|
477
|
-
description: "Delete a checkpoint.",
|
|
518
|
+
error: removing,
|
|
519
|
+
description: "Delete a checkpoint, once the restores that read it are done.",
|
|
478
520
|
input: ById
|
|
479
521
|
}),
|
|
522
|
+
Action.make("prebuildCheckpoint", {
|
|
523
|
+
...write,
|
|
524
|
+
error: creating,
|
|
525
|
+
description: "Make checkpoint id from a machine the host builds from the spec, setup and all, and deletes after. A checkpoint id that exists is the answer, and two prebuilds of one id share one build.",
|
|
526
|
+
input: PrebuildRequest,
|
|
527
|
+
success: Prebuilt
|
|
528
|
+
}),
|
|
480
529
|
Action.make("getHost", {
|
|
481
530
|
...read,
|
|
482
531
|
error: [Invalid],
|
|
@@ -498,7 +547,7 @@ const actionsByName = Action.byName(Http.actions);
|
|
|
498
547
|
//#endregion
|
|
499
548
|
//#region src/release.ts
|
|
500
549
|
/** Also the version of the clankerbox CLI released with it. */
|
|
501
|
-
const version = "0.
|
|
550
|
+
const version = "0.19.0";
|
|
502
551
|
/** major.minor: releases that share it speak the same API. */
|
|
503
552
|
const release = (of) => of.split(".").slice(0, 2).join(".");
|
|
504
553
|
/** A host refuses a request whose `release` differs from its own, or that has none. */
|
|
@@ -700,9 +749,10 @@ const make = (hosts, options) => Effect.gen(function* () {
|
|
|
700
749
|
restoreMachine: (input) => onResource("restoreMachine", input, input.name),
|
|
701
750
|
getCheckpoint: (input) => onResource("getCheckpoint", input),
|
|
702
751
|
captureCheckpoint: (input) => onResource("captureCheckpoint", input, input.name),
|
|
703
|
-
deleteCheckpoint: (input) => deleting(onResource("deleteCheckpoint", input))
|
|
752
|
+
deleteCheckpoint: (input) => deleting(onResource("deleteCheckpoint", input)),
|
|
753
|
+
prebuildCheckpoint: (input) => onResource("prebuildCheckpoint", input)
|
|
704
754
|
};
|
|
705
755
|
});
|
|
706
756
|
const layer = (hosts, options) => Layer.effect(Client, make(hosts, options));
|
|
707
757
|
//#endregion
|
|
708
|
-
export {
|
|
758
|
+
export { formatId as A, NotFound as B, SshLogin as C, HostId as D, stateLabel as E, Conflict as F, ScriptFailed as G, NotOffered as H, HostError as I, Unsizable as J, Superseded as K, Internal as L, parseName as M, Capacity as N, Id as O, ClankerboxError as P, Invalid as R, SshEndpoint as S, Usage as T, PinMismatch as U, NotMade as V, Refused as W, hostErrors as X, WrongState as Y, retryable as Z, Phase as _, release as a, Runtime as b, Http as c, Checkpoint as d, CreateRequest as f, MachineSpec as g, Machine as h, describeIssues as i, parseId as j, Name as k, actionsByName as l, Host as m, layer as n, version as o, Desired as p, Unavailable as q, describeFileError as r, versionHeader as s, client_exports as t, readTimeout as u, PrebuildRequest as v, TailnetStatus as w, Setup as x, Prebuilt as y, Missing as z };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { A as Conflict, B as ScriptFailed, C as stateLabel, D as readTimeout, E as actionsByName, F as NotFound, G as hostErrors, H as Unavailable, I as NotMade, K as retryable, L as NotOffered, M as Internal, N as Invalid, O as Capacity, P as Missing, R as PinMismatch, S as Usage, T as Http, U as Unsizable, V as Superseded, W as WrongState, _ as Runtime, b as SshLogin, c as CreateRequest, d as Machine, f as MachineSpec, g as Reading, h as Prebuilt, i as Interface, j as HostError, k as ClankerboxError, l as Desired, m as PrebuildRequest, n as CreateOptions$1, o as client_d_exports, p as Phase, s as Checkpoint, u as Host, v as Setup, w as Declared, x as TailnetStatus, y as SshEndpoint, z as Refused } from "./client-BodRGKAX.mjs";
|
|
2
2
|
import { Effect, FileSystem, Path, PlatformError, Schema, Scope } from "effect";
|
|
3
3
|
//#region src/ids.d.ts
|
|
4
4
|
export declare const HostId: Schema.String;
|
|
@@ -15,7 +15,7 @@ export declare const parseName: (name: string) => Effect.Effect<string, Invalid>
|
|
|
15
15
|
/** Checks both parts and the whole. */
|
|
16
16
|
export declare const formatId: (host: string, name: string) => Effect.Effect<string, Invalid>;
|
|
17
17
|
declare namespace prebuild_d_exports {
|
|
18
|
-
export {
|
|
18
|
+
export { CreateOptions, Created, build, create, nameOf };
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* A digest of the spec's label, base, sizes, setup script as sent, and the host's runtime
|
|
@@ -34,26 +34,17 @@ interface Created {
|
|
|
34
34
|
readonly prebuild?: Checkpoint | undefined;
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
37
|
-
* `client.create`, restoring the spec's prebuild when the host it is placed on has one
|
|
38
|
-
*
|
|
37
|
+
* `client.create`, restoring the spec's prebuild when the host it is placed on has one, unless
|
|
38
|
+
* `fresh`. A failed restore is the reply.
|
|
39
39
|
*/
|
|
40
40
|
declare const create: (client: Interface, name: string, spec: MachineSpec, options?: CreateOptions) => Effect.Effect<Created, ClankerboxError>;
|
|
41
|
-
interface Built {
|
|
42
|
-
readonly checkpoint: Checkpoint;
|
|
43
|
-
readonly built: boolean;
|
|
44
|
-
/** The builder's ID when its delete failed: it may still run, holding its RAM. */
|
|
45
|
-
readonly leftover?: string | undefined;
|
|
46
|
-
}
|
|
47
41
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* failed is deleted and built again, and one still running is `Conflict{busy}`, as its capture
|
|
51
|
-
* holds it. Of two builds of one spec at once, the second's capture is `Conflict`, and neither
|
|
52
|
-
* touches the other's machine.
|
|
42
|
+
* Asks the host a create of the spec is placed on for the spec's prebuild, which it builds with a
|
|
43
|
+
* machine of its own unless it has it. Two builds of one spec at once share the host's one build.
|
|
53
44
|
*/
|
|
54
45
|
declare const build: (client: Interface, spec: MachineSpec & {
|
|
55
46
|
readonly setup: Setup;
|
|
56
|
-
}, options?: CreateOptions$1) => Effect.Effect<
|
|
47
|
+
}, options?: CreateOptions$1) => Effect.Effect<Prebuilt, ClankerboxError>;
|
|
57
48
|
//#endregion
|
|
58
49
|
//#region src/release.d.ts
|
|
59
50
|
/** Also the version of the clankerbox CLI released with it. */
|
|
@@ -154,4 +145,4 @@ export declare const formatMib: (mib: number) => string;
|
|
|
154
145
|
/** As a size flag takes it: `60G`. */
|
|
155
146
|
export declare const formatGib: (gib: number) => string;
|
|
156
147
|
//#endregion
|
|
157
|
-
export {
|
|
148
|
+
export { Capacity, Checkpoint, ClankerboxError, client_d_exports as Client, Conflict, CreateRequest, Declared, Desired, Host, HostError, Http, Internal, Invalid, Machine, MachineSpec, Missing, NotFound, NotMade, NotOffered, Phase, PinMismatch, prebuild_d_exports as Prebuild, PrebuildRequest, Prebuilt, Reading, Refused, Runtime, ScriptFailed, Setup, SshEndpoint, SshLogin, Superseded, TailnetStatus, Unavailable, Unsizable, Usage, WrongState, actionsByName, hostErrors, readTimeout, retryable, stateLabel };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
-
import { A as
|
|
2
|
+
import { A as formatId, B as NotFound, C as SshLogin, D as HostId, E as stateLabel, F as Conflict, G as ScriptFailed, H as NotOffered, I as HostError, J as Unsizable, K as Superseded, L as Internal, M as parseName, N as Capacity, O as Id, P as ClankerboxError, R as Invalid, S as SshEndpoint, T as Usage, U as PinMismatch, V as NotMade, W as Refused, X as hostErrors, Y as WrongState, Z as retryable, _ as Phase, a as release, b as Runtime, c as Http, d as Checkpoint, f as CreateRequest, g as MachineSpec, h as Machine, i as describeIssues, j as parseId, k as Name, l as actionsByName, m as Host, o as version, p as Desired, q as Unavailable, r as describeFileError, s as versionHeader, t as client_exports, u as readTimeout, v as PrebuildRequest, w as TailnetStatus, x as Setup, y as Prebuilt, z as Missing } from "./client-BwhQ_WUi.mjs";
|
|
3
3
|
import { Effect, FileSystem, Option, Path, Predicate, Record, Schema } from "effect";
|
|
4
4
|
import { Base64, Hex } from "effect/encoding";
|
|
5
5
|
//#region src/prebuild.ts
|
|
@@ -10,7 +10,6 @@ var prebuild_exports = /* @__PURE__ */ __exportAll({
|
|
|
10
10
|
});
|
|
11
11
|
const prefix = "prebuilt-";
|
|
12
12
|
const digestDigits = 12;
|
|
13
|
-
const builderBytes = 8;
|
|
14
13
|
/**
|
|
15
14
|
* A digest of the spec's label, base, sizes, setup script as sent, and the host's runtime
|
|
16
15
|
* version: a `ram` checkpoint restores only under the release that saved it, so after a runtime
|
|
@@ -28,15 +27,15 @@ const nameOf = (spec, host) => Effect.promise(() => globalThis.crypto.subtle.dig
|
|
|
28
27
|
])))).pipe(Effect.map((digest) => `${prefix}${Hex.encode(new Uint8Array(digest)).slice(0, digestDigits)}`));
|
|
29
28
|
const lookup = (client, id) => client.getCheckpoint({ id }).pipe(Effect.map(Option.some), Effect.catchTag("NotFound", () => Effect.succeedNone));
|
|
30
29
|
/**
|
|
31
|
-
* `client.create`, restoring the spec's prebuild when the host it is placed on has one
|
|
32
|
-
*
|
|
30
|
+
* `client.create`, restoring the spec's prebuild when the host it is placed on has one, unless
|
|
31
|
+
* `fresh`. A failed restore is the reply.
|
|
33
32
|
*/
|
|
34
33
|
const create = (client, name, spec, options) => Effect.gen(function* () {
|
|
35
34
|
if (spec.setup === void 0 || options?.fresh === true) return { machine: yield* client.create(name, spec, { host: options?.host }) };
|
|
36
35
|
const host = yield* client.place(spec.base, options);
|
|
37
36
|
const id = yield* formatId(host.id, yield* nameOf(spec, host));
|
|
38
37
|
const found = yield* lookup(client, id);
|
|
39
|
-
if (Option.isSome(found)
|
|
38
|
+
if (Option.isSome(found)) return {
|
|
40
39
|
machine: yield* client.restoreMachine({
|
|
41
40
|
checkpoint: id,
|
|
42
41
|
name
|
|
@@ -46,47 +45,16 @@ const create = (client, name, spec, options) => Effect.gen(function* () {
|
|
|
46
45
|
return { machine: yield* client.create(name, spec, { host: host.id }) };
|
|
47
46
|
});
|
|
48
47
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* failed is deleted and built again, and one still running is `Conflict{busy}`, as its capture
|
|
52
|
-
* holds it. Of two builds of one spec at once, the second's capture is `Conflict`, and neither
|
|
53
|
-
* touches the other's machine.
|
|
48
|
+
* Asks the host a create of the spec is placed on for the spec's prebuild, which it builds with a
|
|
49
|
+
* machine of its own unless it has it. Two builds of one spec at once share the host's one build.
|
|
54
50
|
*/
|
|
55
51
|
const build = (client, spec, options) => Effect.gen(function* () {
|
|
56
52
|
const host = yield* client.place(spec.base, options);
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (isReady(found.value)) return {
|
|
63
|
-
checkpoint: found.value,
|
|
64
|
-
built: false
|
|
65
|
-
};
|
|
66
|
-
if (action.status === "running") return yield* new Conflict({
|
|
67
|
-
message: `prebuild ${id} is busy: its ${action.name} is running`,
|
|
68
|
-
kind: "busy",
|
|
69
|
-
host: host.id,
|
|
70
|
-
action: "captureCheckpoint",
|
|
71
|
-
id
|
|
72
|
-
});
|
|
73
|
-
yield* client.deleteCheckpoint({ id });
|
|
74
|
-
}
|
|
75
|
-
const builder = `prebuilding-${Hex.encode(globalThis.crypto.getRandomValues(new Uint8Array(builderBytes)))}`;
|
|
76
|
-
const builderId = yield* formatId(host.id, builder);
|
|
77
|
-
const removal = client.deleteMachine({ id: builderId });
|
|
78
|
-
return {
|
|
79
|
-
checkpoint: yield* Effect.gen(function* () {
|
|
80
|
-
yield* client.create(builder, spec, { host: host.id });
|
|
81
|
-
if (host.captureFrom === "stopped") yield* client.stopMachine({ id: builderId });
|
|
82
|
-
return yield* client.captureCheckpoint({
|
|
83
|
-
machine: builderId,
|
|
84
|
-
name
|
|
85
|
-
});
|
|
86
|
-
}).pipe(Effect.onError(() => Effect.ignore(removal))),
|
|
87
|
-
built: true,
|
|
88
|
-
leftover: yield* removal.pipe(Effect.as(void 0), Effect.catch(() => Effect.succeed(builderId)))
|
|
89
|
-
};
|
|
53
|
+
const id = yield* formatId(host.id, yield* nameOf(spec, host));
|
|
54
|
+
return yield* client.prebuildCheckpoint({
|
|
55
|
+
id,
|
|
56
|
+
...spec
|
|
57
|
+
});
|
|
90
58
|
});
|
|
91
59
|
//#endregion
|
|
92
60
|
//#region src/setup.ts
|
|
@@ -248,7 +216,7 @@ const specRequest = (what, profile, overrides, names) => Effect.gen(function* ()
|
|
|
248
216
|
* either is `WrongState`, naming what it lacks and why.
|
|
249
217
|
*/
|
|
250
218
|
const sshTarget = (machine) => {
|
|
251
|
-
const { id, ssh: login, hostKey
|
|
219
|
+
const { id, ssh: login, hostKey } = machine;
|
|
252
220
|
if (login !== void 0 && hostKey !== void 0) return Effect.succeed({
|
|
253
221
|
id,
|
|
254
222
|
login,
|
|
@@ -256,7 +224,7 @@ const sshTarget = (machine) => {
|
|
|
256
224
|
});
|
|
257
225
|
const lacks = login === void 0 ? "SSH endpoint" : "SSH host key on record";
|
|
258
226
|
const state = stateLabel(machine);
|
|
259
|
-
const message = `${id} has no ${lacks} (${state}
|
|
227
|
+
const message = `${id} has no ${lacks} (${state}): see clankerbox get ${id}`;
|
|
260
228
|
return Effect.fail(new WrongState({
|
|
261
229
|
message,
|
|
262
230
|
machine: id,
|
|
@@ -306,4 +274,4 @@ const formatMib = (mib) => mib >= 1024 && mib % 512 === 0 ? `${mib / mibPerGib}G
|
|
|
306
274
|
/** As a size flag takes it: `60G`. */
|
|
307
275
|
const formatGib = (gib) => `${gib}G`;
|
|
308
276
|
//#endregion
|
|
309
|
-
export {
|
|
277
|
+
export { Capacity, Checkpoint, ClankerboxError, client_exports as Client, Conflict, CreateRequest, Desired, Host, HostError, HostId, Http, Id, Internal, Invalid, Machine, MachineSpec, Missing, Name, NotFound, NotMade, NotOffered, Phase, PinMismatch, prebuild_exports as Prebuild, PrebuildRequest, Prebuilt, Profile, Refused, Runtime, ScriptFailed, Setup, SshEndpoint, SshLogin, Superseded, TailnetStatus, Unavailable, Unsizable, Usage, WrongState, actionsByName, describeFileError, describeIssues, formatGib, formatId, formatMib, hostErrors, knownHostsLine, loadProfile, mibPerGib, packRecipe, parseId, parseName, pinnedSsh, readSetup, readTimeout, release, retryable, specRequest, sshTarget, stateLabel, version, versionHeader };
|
package/dist/node.d.mts
CHANGED
package/dist/node.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjermundgaraba/clankerbox-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"description": "clankerbox's API contract and client library, for Effect",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -27,21 +27,20 @@
|
|
|
27
27
|
"publishConfig": {
|
|
28
28
|
"access": "public"
|
|
29
29
|
},
|
|
30
|
-
"dependencies": {
|
|
31
|
-
"@gjermundgaraba/effect-actions": "0.17.0"
|
|
32
|
-
},
|
|
33
30
|
"devDependencies": {
|
|
34
|
-
"@effect/platform-node": "4.0.
|
|
35
|
-
"@effect/vitest": "4.0.
|
|
36
|
-
"@
|
|
37
|
-
"
|
|
31
|
+
"@effect/platform-node": "4.0.5",
|
|
32
|
+
"@effect/vitest": "4.0.5",
|
|
33
|
+
"@gjermundgaraba/effect-actions": "0.18.2",
|
|
34
|
+
"@types/node": "26.6.5",
|
|
35
|
+
"effect": "4.0.5",
|
|
38
36
|
"typescript": "7.0.2",
|
|
39
|
-
"vite": "npm:@voidzero-dev/vite-plus-core@1.
|
|
40
|
-
"vite-plus": "1.
|
|
41
|
-
"vitest": "5.0.
|
|
37
|
+
"vite": "npm:@voidzero-dev/vite-plus-core@1.3.0",
|
|
38
|
+
"vite-plus": "1.3.0",
|
|
39
|
+
"vitest": "5.0.5"
|
|
42
40
|
},
|
|
43
41
|
"peerDependencies": {
|
|
44
42
|
"@effect/platform-node": "~4.0.4",
|
|
43
|
+
"@gjermundgaraba/effect-actions": "^0.18.0",
|
|
45
44
|
"effect": "~4.0.4"
|
|
46
45
|
},
|
|
47
46
|
"peerDependenciesMeta": {
|