@johannc-dev/zyrk 0.2.0 → 0.2.2
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 +8 -1
- package/dist/cli.d.ts +6 -1
- package/dist/cli.js +44 -8
- package/dist/client.d.ts +17 -4
- package/dist/client.js +515 -18
- package/dist/contracts.d.ts +16 -0
- package/dist/contracts.js +14 -0
- package/dist/errors.d.ts +9 -1
- package/dist/errors.js +6 -1
- package/dist/export.d.ts +27 -8
- package/dist/export.js +149 -19
- package/dist/hourfile.d.ts +3 -1
- package/dist/hourfile.js +7 -0
- package/dist/limits.d.ts +16 -2
- package/dist/limits.js +2 -0
- package/dist/local-data.d.ts +21 -4
- package/dist/local-data.js +52 -1
- package/dist/local-replay.d.ts +5 -5
- package/dist/local-replay.js +4 -3
- package/dist/local-storage.d.ts +2 -2
- package/dist/local.d.ts +2 -2
- package/dist/local.js +166 -35
- package/dist/sandbox-bootstrap.js +231 -9
- package/dist/sdk.d.ts +260 -29
- package/dist/sdk.js +14 -0
- package/dist/stream.d.ts +52 -4
- package/dist/stream.js +111 -13
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @johannc-dev/zyrk 0.2
|
|
2
2
|
|
|
3
|
-
SDK et CLI des fonctions hébergées Zyrk (
|
|
3
|
+
SDK et CLI des fonctions hébergées Zyrk (V8). Node.js 24
|
|
4
4
|
minimum. Ce package contient les types du programme, quelques aides de
|
|
5
5
|
lecture, le compilateur `zyrk build`, le client HTTP et le flux d'événements.
|
|
6
6
|
Le moteur, le stockage et le sandbox restent sur le serveur.
|
|
@@ -53,6 +53,13 @@ npx zyrk run wallet countBuys '{"wallet":"…","sinceMs":0,"untilMs":3600000}'
|
|
|
53
53
|
autres API réseau dans votre code, et l'ancienne API 0.1 (`ctx.data.query`,
|
|
54
54
|
`ctx.data.pages`) avec un guide de migration.
|
|
55
55
|
|
|
56
|
+
Supprimer un programme : `npx zyrk delete wallet` (demande confirmation ;
|
|
57
|
+
`--yes` dans un script) ou `client.delete("wallet")`. Partent ses versions,
|
|
58
|
+
son état, ses abonnements, ses exécutions (celles en cours sont annulées) et
|
|
59
|
+
ses replays ; `ctx.storage` reste (il appartient au compte). La place est
|
|
60
|
+
libérée tout de suite et le même nom redéployé repart de zéro. Un programme
|
|
61
|
+
absent répond `404 program_not_found`.
|
|
62
|
+
|
|
56
63
|
Modules :
|
|
57
64
|
|
|
58
65
|
| Import | Contenu |
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
export declare const VERSION = "0.2.
|
|
2
|
+
export declare const VERSION = "0.2.2";
|
|
3
3
|
/** `2026-11-07`, `2026-11-07T13:00:00Z` or milliseconds since the epoch. */
|
|
4
4
|
export declare function timeOf(text: string): number;
|
|
5
|
+
/**
|
|
6
|
+
* Whether `zyrk delete` may go on: `--yes`, or a `y` typed at the prompt.
|
|
7
|
+
* Without a terminal (a script, CI) and without `--yes` it refuses.
|
|
8
|
+
*/
|
|
9
|
+
export declare function confirmDeletion(name: string, yes: boolean, interactive?: boolean): Promise<boolean>;
|
package/dist/cli.js
CHANGED
|
@@ -5,10 +5,10 @@ import { ChildProcessSpawner } from "effect/process";
|
|
|
5
5
|
import { BUNDLE_PATH, writeBundleEffect } from "./build.js";
|
|
6
6
|
import { ZyrkClient } from "./client.js";
|
|
7
7
|
import { decode, Json } from "./contracts.js";
|
|
8
|
-
import { exportHistory, exportTotals, exportVolumeSearch, } from "./export.js";
|
|
8
|
+
import { exportHistory, exportTotals, exportVolumeSearch, exportCompute, } from "./export.js";
|
|
9
9
|
import { LocalRunner } from "./local.js";
|
|
10
10
|
import { DecodeError, messageOf, } from "./errors.js";
|
|
11
|
-
export const VERSION = "0.2.
|
|
11
|
+
export const VERSION = "0.2.2";
|
|
12
12
|
const print = (value) => Console.log(JSON.stringify(value, null, 2));
|
|
13
13
|
const entry = Argument.String("entry.ts").pipe(Argument.withDescription("TypeScript or JavaScript entry point of the program"));
|
|
14
14
|
const program = Argument.String("program").pipe(Argument.withDescription("Program name"));
|
|
@@ -47,6 +47,26 @@ export function timeOf(text) {
|
|
|
47
47
|
throw new Error(`Not a date: ${text}`);
|
|
48
48
|
return ms;
|
|
49
49
|
}
|
|
50
|
+
export async function confirmDeletion(name, yes, interactive = process.stdin.isTTY === true) {
|
|
51
|
+
if (yes)
|
|
52
|
+
return true;
|
|
53
|
+
if (!interactive) {
|
|
54
|
+
process.stderr.write(`error[NotConfirmed]: zyrk delete ${name} deletes the program, its state, subscriptions, executions and replays: add --yes to confirm without a terminal\n`);
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
const { createInterface } = await import("node:readline/promises");
|
|
58
|
+
const prompt = createInterface({
|
|
59
|
+
input: process.stdin,
|
|
60
|
+
output: process.stderr,
|
|
61
|
+
});
|
|
62
|
+
try {
|
|
63
|
+
const answer = await prompt.question(`Delete program ${name} with its state, subscriptions, executions and replays (ctx.storage stays)? [y/N] `);
|
|
64
|
+
return /^y(es)?$/i.test(answer.trim());
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
prompt.close();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
50
70
|
const local = (name, body) => Effect.promise(() => body().catch((error) => {
|
|
51
71
|
process.stderr.write(`error[${name}]: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
52
72
|
process.exitCode = 1;
|
|
@@ -65,11 +85,12 @@ const exportCommand = Command.make("export", {
|
|
|
65
85
|
"with-events": flag("with-events", "Export pool events too (implies --with-market)"),
|
|
66
86
|
"with-order": flag("with-order", "Export batch.order (on-chain order)"),
|
|
67
87
|
"with-tx": flag("with-tx", "Export batch.tx (transaction of each trade, place in it)"),
|
|
68
|
-
refresh: flag("refresh", "Download every hour again (a finished export only re-downloads the hours that were open or not sealed)"),
|
|
69
|
-
totals: optionalString("totals", "Also save
|
|
70
|
-
quote: optionalString("quote", "Quote mint of --totals"),
|
|
88
|
+
refresh: flag("refresh", "Download every hour again (a finished export only re-downloads the hours that were open or not sealed, or exported by an older version)"),
|
|
89
|
+
totals: optionalString("totals", "Also save the totals of this mint (ctx.data.tokenTotals, tokenInfo)"),
|
|
90
|
+
quote: optionalString("quote", "Quote mint of --totals, or auto"),
|
|
91
|
+
compute: optionalString("compute", "Also save the answer of ctx.compute(<json plan or array of plans>), computed by the service"),
|
|
71
92
|
"volume-search": optionalString("volume-search", "Also save every page of ctx.data.volumeSearch(<json params>)"),
|
|
72
|
-
rpm: Flag.Int("rpm").pipe(Flag.withDescription("At most this many requests per minute"), Flag.optional),
|
|
93
|
+
rpm: Flag.Int("rpm").pipe(Flag.withDescription("At most this many requests per minute (optional: the server allows 30 a second per account)"), Flag.optional),
|
|
73
94
|
out: Flag.String("out").pipe(Flag.withAlias("o"), Flag.withDescription("Data directory (created, resumed if it exists)"), Flag.withDefault("data")),
|
|
74
95
|
}, (input) => local("export", async () => {
|
|
75
96
|
const url = process.env.TH_API_URL;
|
|
@@ -119,6 +140,12 @@ const exportCommand = Command.make("export", {
|
|
|
119
140
|
await exportTotals(connection, input.out, totals, value(input.quote) ?? null);
|
|
120
141
|
work = true;
|
|
121
142
|
}
|
|
143
|
+
const computeText = value(input.compute);
|
|
144
|
+
if (computeText) {
|
|
145
|
+
const r = await exportCompute(connection, input.out, JSON.parse(computeText));
|
|
146
|
+
process.stderr.write(`compute: ${r.rows === null ? "an error answer (saved: the local run throws it)" : `${r.rows} row(s)`}\n`);
|
|
147
|
+
work = true;
|
|
148
|
+
}
|
|
122
149
|
const volume = value(input["volume-search"]);
|
|
123
150
|
if (volume) {
|
|
124
151
|
const pages = await exportVolumeSearch(connection, input.out, JSON.parse(volume));
|
|
@@ -126,7 +153,7 @@ const exportCommand = Command.make("export", {
|
|
|
126
153
|
work = true;
|
|
127
154
|
}
|
|
128
155
|
if (!work)
|
|
129
|
-
throw new Error("Nothing to export: --token/--wallet, --totals
|
|
156
|
+
throw new Error("Nothing to export: --token/--wallet, --totals, --volume-search or --compute");
|
|
130
157
|
})).pipe(Command.withDescription("Download history (one file per hour, as hosted programs see it) for zyrk dev. Resumes an interrupted export."));
|
|
131
158
|
const devCommand = Command.make("dev", {
|
|
132
159
|
entry,
|
|
@@ -139,7 +166,7 @@ const devCommand = Command.make("dev", {
|
|
|
139
166
|
replay: optionalString("replay", "Replay this subscription over --since/--until: <function> is ignored, json is unused"),
|
|
140
167
|
since: optionalString("since", "Replay start"),
|
|
141
168
|
until: optionalString("until", "Replay end"),
|
|
142
|
-
"events-per-delivery": Flag.Int("events-per-delivery").pipe(Flag.withDescription("Events per replayed delivery (1 to 32, default 1)"), Flag.optional),
|
|
169
|
+
"events-per-delivery": Flag.Int("events-per-delivery").pipe(Flag.withDescription("Events per replayed delivery (1 to 32, default 32; interval triggers: 1)"), Flag.optional),
|
|
143
170
|
quiet: flag("quiet", "Do not print logs and emits as they happen"),
|
|
144
171
|
"no-typecheck": noTypecheck,
|
|
145
172
|
}, (input) => local("dev", async () => {
|
|
@@ -248,6 +275,15 @@ const zyrk = Command.make("zyrk").pipe(Command.withDescription("Zyrk hosted func
|
|
|
248
275
|
Command.make("programs", {}, () => withClient((c) => c.programs())).pipe(Command.withDescription("List the programs of the account")),
|
|
249
276
|
onArgument("inspect", "Show a program", program, (c, p) => c.inspect(p)),
|
|
250
277
|
onArgument("executions", "Recent executions of a program", program, (c, p) => c.executions(p)),
|
|
278
|
+
Command.make("delete", {
|
|
279
|
+
program,
|
|
280
|
+
yes: flag("yes", "Do not ask for confirmation"),
|
|
281
|
+
}, (input) => Effect.promise(() => confirmDeletion(input.program, input.yes)).pipe(Effect.flatMap((confirmed) => {
|
|
282
|
+
if (confirmed)
|
|
283
|
+
return withClient((c) => c.delete(input.program));
|
|
284
|
+
process.exitCode = 1;
|
|
285
|
+
return Effect.void;
|
|
286
|
+
}))).pipe(Command.withDescription("Delete a program and everything bound to it (state, subscriptions, executions, replays); ctx.storage stays. Asks first unless --yes")),
|
|
251
287
|
onArgument("pause", "Pause a program", program, (c, p) => c.pause(p, true)),
|
|
252
288
|
onArgument("resume", "Resume a program", program, (c, p) => c.pause(p, false)),
|
|
253
289
|
exportCommand,
|
package/dist/client.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Context, Effect, Layer } from "effect";
|
|
2
|
-
import { Job, Json, ProgramSummary, type JobResult } from "./contracts.js";
|
|
2
|
+
import { Job, Json, ProgramDeleted, ProgramSummary, type JobResult } from "./contracts.js";
|
|
3
3
|
import { ApiError, ConfigError, DecodeError, ExecutionEnded, ExecutionFailed, NetworkError, WaitTimeout } from "./errors.js";
|
|
4
4
|
export * from "./errors.js";
|
|
5
|
-
export type { Job, JobResult, ProgramSummary } from "./contracts.js";
|
|
5
|
+
export type { Job, JobResult, ProgramDeleted, ProgramSummary, } from "./contracts.js";
|
|
6
6
|
import type { ReplayFeedItem, ReplayRecord, ReplayRequest } from "./sdk.js";
|
|
7
7
|
export type { ReplayFeedItem, ReplayRecord, ReplayRequest } from "./sdk.js";
|
|
8
8
|
export interface ClientConfig {
|
|
@@ -18,7 +18,11 @@ export interface StartInput {
|
|
|
18
18
|
readonly requestId?: string;
|
|
19
19
|
}
|
|
20
20
|
export interface WaitOptions {
|
|
21
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Delay between two status checks, in milliseconds. Without it, each check
|
|
23
|
+
* is held by the service until the execution ends (at most 10 s), and a
|
|
24
|
+
* service that cannot hold is checked once a second.
|
|
25
|
+
*/
|
|
22
26
|
readonly pollMs?: number;
|
|
23
27
|
/** Give up after this many milliseconds (default: never). The execution keeps running. */
|
|
24
28
|
readonly timeoutMs?: number;
|
|
@@ -42,6 +46,13 @@ export interface ZyrkClientService {
|
|
|
42
46
|
programs(): Effect.Effect<readonly ProgramSummary[], RequestError>;
|
|
43
47
|
inspect(program: string): Effect.Effect<Json, RequestError>;
|
|
44
48
|
pause(program: string, paused?: boolean): Effect.Effect<Json, RequestError>;
|
|
49
|
+
/**
|
|
50
|
+
* Deletes the program and everything bound to it (versions, state,
|
|
51
|
+
* subscriptions, executions, replays); what runs of it is cancelled.
|
|
52
|
+
* The account's storage stays. Fails with `program_not_found` (404) when
|
|
53
|
+
* there is no such program, also when a retried call already deleted it.
|
|
54
|
+
*/
|
|
55
|
+
delete(program: string): Effect.Effect<ProgramDeleted, RequestError>;
|
|
45
56
|
/** Recent executions of a program (summaries). */
|
|
46
57
|
executions(program: string): Effect.Effect<Json, RequestError>;
|
|
47
58
|
/** Starts an execution and returns its id. */
|
|
@@ -121,6 +132,8 @@ export declare class FunctionsClient {
|
|
|
121
132
|
programs(signal?: AbortSignal): Promise<readonly ProgramSummary[]>;
|
|
122
133
|
inspect(program: string, signal?: AbortSignal): Promise<Json>;
|
|
123
134
|
pause(program: string, paused?: boolean, signal?: AbortSignal): Promise<Json>;
|
|
135
|
+
/** See {@link ZyrkClientService.delete}. */
|
|
136
|
+
delete(program: string, signal?: AbortSignal): Promise<ProgramDeleted>;
|
|
124
137
|
executions(program: string, signal?: AbortSignal): Promise<Json>;
|
|
125
138
|
start(program: string, input: StartInput, signal?: AbortSignal): Promise<string>;
|
|
126
139
|
execution(id: string, signal?: AbortSignal): Promise<Job>;
|
|
@@ -154,7 +167,7 @@ export declare class FunctionsClient {
|
|
|
154
167
|
*/
|
|
155
168
|
replayEmits(id: string, afterSeq?: number, signal?: AbortSignal): Promise<ReplayFeedItem[]>;
|
|
156
169
|
}
|
|
157
|
-
/**
|
|
170
|
+
/** The head of a stored object as the HTTP headers describe it. */
|
|
158
171
|
export interface HttpStorageHead {
|
|
159
172
|
readonly key: string;
|
|
160
173
|
readonly size: number;
|