@astrale-os/adapter-astrale 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/dist/astrale.d.ts CHANGED
@@ -18,8 +18,8 @@
18
18
  * account, no wrangler auth — the only credential is the author's Astrale
19
19
  * identity, supplied by the `astrale` CLI session this adapter shells out to.
20
20
  *
21
- * REQUIRES the `services` domain installed on the target instance. An instance
22
- * without it can't host managed deploys — `deploy` fails loud with that hint.
21
+ * Ensures the `services` domain is installed on the target instance before the
22
+ * build/deploy work starts; without it the instance cannot host managed deploys.
23
23
  *
24
24
  * `watch` is identical to the Cloudflare adapter's local dev (wrangler dev on
25
25
  * localhost) — managed deploys change WHERE the worker runs, not how you iterate.
@@ -1 +1 @@
1
- {"version":3,"file":"astrale.d.ts","sourceRoot":"","sources":["../src/astrale.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAmBpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAK7C,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,aAAa,CAAC,aAAa,CAAC,CA8LzF;AAgED,gGAAgG;AAChG,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED;;;oFAGoF;AACpF,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKrD"}
1
+ {"version":3,"file":"astrale.d.ts","sourceRoot":"","sources":["../src/astrale.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAa,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAmB/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAW7C,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,aAAa,CAAC,aAAa,CAAC,CA4NzF;AAqFD,gGAAgG;AAChG,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED;;;oFAGoF;AACpF,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKrD"}
package/dist/astrale.js CHANGED
@@ -18,8 +18,8 @@
18
18
  * account, no wrangler auth — the only credential is the author's Astrale
19
19
  * identity, supplied by the `astrale` CLI session this adapter shells out to.
20
20
  *
21
- * REQUIRES the `services` domain installed on the target instance. An instance
22
- * without it can't host managed deploys — `deploy` fails loud with that hint.
21
+ * Ensures the `services` domain is installed on the target instance before the
22
+ * build/deploy work starts; without it the instance cannot host managed deploys.
23
23
  *
24
24
  * `watch` is identical to the Cloudflare adapter's local dev (wrangler dev on
25
25
  * localhost) — managed deploys change WHERE the worker runs, not how you iterate.
@@ -33,6 +33,7 @@ import { loadDotenvFile } from '@astrale-os/sdk/cli';
33
33
  import { spawn } from 'node:child_process';
34
34
  import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
35
35
  import { join, relative } from 'node:path';
36
+ import { ensureServicesDomainInstalled, runManagedInstallWithRetry, waitForManagedServiceReady, } from './managed-service';
36
37
  const DEFAULT_PORT = 8787;
37
38
  const DEFAULT_SERVICES_ORIGIN = 'services.astrale.ai';
38
39
  export function astrale(envs) {
@@ -78,6 +79,14 @@ export function astrale(envs) {
78
79
  }
79
80
  const servicesOrigin = params.servicesOrigin ?? DEFAULT_SERVICES_ORIGIN;
80
81
  const name = params.name ?? serviceNameFor(ctx.domain.origin);
82
+ const runProjectAstrale = (args) => runAstrale(astraleBin(ctx.projectDir), ctx.projectDir, args);
83
+ await ensureServicesDomainInstalled({
84
+ runAstrale: runProjectAstrale,
85
+ instance,
86
+ servicesOrigin,
87
+ identityArgs: identityArgs(params),
88
+ log,
89
+ });
81
90
  // Build + pack the client SPA: the services worker serves it under /ui.
82
91
  let assetFiles = [];
83
92
  if (ctx.clientDir) {
@@ -165,29 +174,43 @@ export function astrale(envs) {
165
174
  for (const [key, value] of Object.entries(secrets)) {
166
175
  await astraleCall(ctx.projectDir, params, {
167
176
  instance,
168
- path: `/${servicesOrigin}/services/${name}/setSecret`,
177
+ // The service node is placed at the root (`/${serviceSlugFor(origin)}`),
178
+ // not under a `/services` folder.
179
+ path: `/${serviceSlugFor(ctx.domain.origin)}::setSecret`,
169
180
  data: { name: key, value },
170
181
  viaStdin: true,
171
182
  });
172
183
  }
173
184
  }
185
+ // Cloudflare's dispatch namespace can acknowledge a script before the
186
+ // public tenant host is consistently serving the new worker. Installing
187
+ // before `/meta` + JWKS are reachable turns that propagation window into a
188
+ // postInstall fetch abort and leaves partial graph state behind.
189
+ const expectedSchemaHash = await expectedSchemaHashForManagedUrl(ctx, url, log);
190
+ log(`waiting for managed service "${ctx.domain.origin}" at ${url}…`);
191
+ await waitForManagedServiceReady(url, ctx.domain.origin, { log, expectedSchemaHash });
174
192
  // 4. Install the domain on the instance from the hosted URL. The child
175
193
  // kernel fetches the signed bundle, verifies it, and runs its postInstall.
176
194
  // A managed deploy ALWAYS aliases identity — the domain's origin
177
195
  // (`ctx.domain.origin`) is served from the platform host (`…svc.<routing>`)
178
196
  // it never matches — so consent to the override is implicit and required.
179
197
  log(`installing "${ctx.domain.origin}" on "${instance}" from ${url}…`);
180
- await runAstrale(astraleBin(ctx.projectDir), ctx.projectDir, [
181
- 'instance',
198
+ await runManagedInstallWithRetry(() => runAstrale(astraleBin(ctx.projectDir), ctx.projectDir, [
199
+ 'domain',
182
200
  'install',
183
201
  url,
202
+ '--direct',
184
203
  '-i',
185
204
  instance,
186
205
  '--allow-identity-override',
187
206
  '--json',
188
207
  '--timeout',
189
208
  '240000',
190
- ]);
209
+ ...identityArgs(params),
210
+ ]), {
211
+ log,
212
+ beforeRetry: () => waitForManagedServiceReady(url, ctx.domain.origin, { log, expectedSchemaHash }),
213
+ });
191
214
  return {
192
215
  url,
193
216
  nextSteps: ` installed on "${instance}" — call it:\n` +
@@ -199,6 +222,21 @@ export function astrale(envs) {
199
222
  },
200
223
  });
201
224
  }
225
+ async function expectedSchemaHashForManagedUrl(ctx, url, log) {
226
+ if (!ctx.schemaHashForUrl)
227
+ return undefined;
228
+ try {
229
+ return await ctx.schemaHashForUrl(url);
230
+ }
231
+ catch (error) {
232
+ log(`warning: could not compute expected schema hash for ${url}; ` +
233
+ `readiness will verify domain/JWKS only (${errorMessage(error)})`);
234
+ return undefined;
235
+ }
236
+ }
237
+ function errorMessage(error) {
238
+ return error instanceof Error ? error.message : String(error);
239
+ }
202
240
  /** Serving MIME by file extension. The provider serves each asset with the type
203
241
  * declared here VERBATIM — Cloudflare does NOT re-infer it from the path, so an
204
242
  * unset type ships `application/octet-stream` and the browser DOWNLOADS the file
@@ -284,8 +322,7 @@ async function astraleCall(projectDir, params, call) {
284
322
  // default. Target the instance (`-i`), not admin — the services domain lives
285
323
  // on the instance.
286
324
  const args = ['call', call.path, '-i', call.instance, '--json', '--timeout', '240000'];
287
- if (params.identity)
288
- args.push('--as', params.identity);
325
+ args.push(...identityArgs(params));
289
326
  const payload = JSON.stringify(call.data);
290
327
  if (!call.viaStdin)
291
328
  args.push('--data', payload);
@@ -297,6 +334,9 @@ async function astraleCall(projectDir, params, call) {
297
334
  throw new Error(`astrale call ${call.path}: could not parse CLI output: ${out.slice(0, 300)}`);
298
335
  }
299
336
  }
337
+ function identityArgs(params) {
338
+ return params.identity ? ['--as', params.identity] : [];
339
+ }
300
340
  /** Spawn the astrale CLI, feed optional stdin, return stdout+stderr. Throws on non-zero exit. */
301
341
  async function runAstrale(bin, cwd, args, stdin) {
302
342
  const { code, out } = await new Promise((resolve, reject) => {
@@ -1 +1 @@
1
- {"version":3,"file":"astrale.js","sourceRoot":"","sources":["../src/astrale.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"astrale.js","sourceRoot":"","sources":["../src/astrale.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ type ManagedMeta = {
2
+ domainName?: string;
3
+ iss?: string;
4
+ schemaHash?: string;
5
+ };
6
+ type JsonFetch = typeof fetch;
7
+ type SleepFn = (ms: number) => Promise<void>;
8
+ type RunAstrale = (args: string[]) => Promise<string>;
9
+ type ManagedReadyOptions = {
10
+ timeoutMs?: number;
11
+ retryMs?: number;
12
+ expectedSchemaHash?: string;
13
+ fetch?: JsonFetch;
14
+ sleep?: SleepFn;
15
+ log?: (line: string) => void;
16
+ };
17
+ type ManagedInstallRetryOptions = {
18
+ attempts?: number;
19
+ retryMs?: number;
20
+ sleep?: SleepFn;
21
+ log?: (line: string) => void;
22
+ beforeRetry?: () => Promise<unknown>;
23
+ };
24
+ type EnsureServicesDomainOptions = {
25
+ runAstrale: RunAstrale;
26
+ instance: string;
27
+ servicesOrigin: string;
28
+ identityArgs?: string[];
29
+ log: (line: string) => void;
30
+ };
31
+ export declare function waitForManagedServiceReady(url: string, expectedDomain: string, opts?: ManagedReadyOptions): Promise<ManagedMeta>;
32
+ export declare function runManagedInstallWithRetry<T>(run: () => Promise<T>, opts?: ManagedInstallRetryOptions): Promise<T>;
33
+ export declare function isTransientManagedInstallError(error: unknown): boolean;
34
+ export declare function ensureServicesDomainInstalled(opts: EnsureServicesDomainOptions): Promise<void>;
35
+ export {};
36
+ //# sourceMappingURL=managed-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"managed-service.d.ts","sourceRoot":"","sources":["../src/managed-service.ts"],"names":[],"mappings":"AAKA,KAAK,WAAW,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAC7E,KAAK,SAAS,GAAG,OAAO,KAAK,CAAA;AAC7B,KAAK,OAAO,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAC5C,KAAK,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;AAErD,KAAK,mBAAmB,GAAG;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC7B,CAAA;AAED,KAAK,0BAA0B,GAAG;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC5B,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;CACrC,CAAA;AAED,KAAK,2BAA2B,GAAG;IACjC,UAAU,EAAE,UAAU,CAAA;IACtB,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,MAAM,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC5B,CAAA;AAED,wBAAsB,0BAA0B,CAC9C,GAAG,EAAE,MAAM,EACX,cAAc,EAAE,MAAM,EACtB,IAAI,GAAE,mBAAwB,GAC7B,OAAO,CAAC,WAAW,CAAC,CA4CtB;AAED,wBAAsB,0BAA0B,CAAC,CAAC,EAChD,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACrB,IAAI,GAAE,0BAA+B,GACpC,OAAO,CAAC,CAAC,CAAC,CAsBZ;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAItE;AAED,wBAAsB,6BAA6B,CACjD,IAAI,EAAE,2BAA2B,GAChC,OAAO,CAAC,IAAI,CAAC,CAmCf"}
@@ -0,0 +1,120 @@
1
+ const MANAGED_READY_TIMEOUT_MS = 90_000;
2
+ const MANAGED_READY_FETCH_TIMEOUT_MS = 5_000;
3
+ const MANAGED_READY_RETRY_MS = 1_000;
4
+ const MANAGED_INSTALL_ATTEMPTS = 3;
5
+ export async function waitForManagedServiceReady(url, expectedDomain, opts = {}) {
6
+ const base = normalizeBaseUrl(url);
7
+ const fetcher = opts.fetch ?? fetch;
8
+ const sleepFn = opts.sleep ?? sleep;
9
+ const retryMs = opts.retryMs ?? MANAGED_READY_RETRY_MS;
10
+ const timeoutMs = opts.timeoutMs ?? MANAGED_READY_TIMEOUT_MS;
11
+ const deadline = Date.now() + timeoutMs;
12
+ let lastReason = '';
13
+ while (true) {
14
+ let reason = 'not checked';
15
+ try {
16
+ const meta = await fetchJson(fetcher, `${base}/meta`);
17
+ const metaIssuer = meta.iss ? normalizeBaseUrl(meta.iss) : base;
18
+ if (meta.domainName !== expectedDomain) {
19
+ reason = `/meta domainName=${JSON.stringify(meta.domainName)} expected=${expectedDomain}`;
20
+ }
21
+ else if (opts.expectedSchemaHash && meta.schemaHash !== opts.expectedSchemaHash) {
22
+ reason = `/meta schemaHash=${JSON.stringify(meta.schemaHash)} expected=${opts.expectedSchemaHash}`;
23
+ }
24
+ else if (metaIssuer !== base) {
25
+ reason = `/meta iss=${meta.iss} expected=${base}`;
26
+ }
27
+ else {
28
+ const jwks = await fetchJson(fetcher, `${metaIssuer}/.well-known/jwks.json`);
29
+ const keys = Array.isArray(jwks.keys) ? jwks.keys : [];
30
+ if (keys.length)
31
+ return meta;
32
+ reason = 'JWKS returned no keys';
33
+ }
34
+ }
35
+ catch (error) {
36
+ reason = errorMessage(error);
37
+ }
38
+ if (reason !== lastReason) {
39
+ opts.log?.(` service not ready yet: ${reason}`);
40
+ lastReason = reason;
41
+ }
42
+ const remaining = deadline - Date.now();
43
+ if (remaining <= 0) {
44
+ throw new Error(`managed service ${base} was not ready within ${timeoutMs}ms: ${lastReason}`);
45
+ }
46
+ await sleepFn(Math.min(retryMs, remaining));
47
+ }
48
+ }
49
+ export async function runManagedInstallWithRetry(run, opts = {}) {
50
+ const attempts = opts.attempts ?? MANAGED_INSTALL_ATTEMPTS;
51
+ const retryMs = opts.retryMs ?? MANAGED_READY_RETRY_MS;
52
+ const sleepFn = opts.sleep ?? sleep;
53
+ let lastError;
54
+ for (let attempt = 1; attempt <= attempts; attempt++) {
55
+ try {
56
+ return await run();
57
+ }
58
+ catch (error) {
59
+ lastError = error;
60
+ if (attempt >= attempts || !isTransientManagedInstallError(error))
61
+ throw error;
62
+ opts.log?.(` install attempt ${attempt}/${attempts} hit a transient failure: ` +
63
+ `${errorMessage(error).slice(0, 220)}; retrying…`);
64
+ await opts.beforeRetry?.();
65
+ await sleepFn(retryMs);
66
+ }
67
+ }
68
+ throw lastError instanceof Error ? lastError : new Error(String(lastError));
69
+ }
70
+ export function isTransientManagedInstallError(error) {
71
+ return /network fetch failed|operation was aborted|fetch failed|und_err|econnreset|etimedout|timeout|503|504|522|524|worker startup timed out/i.test(errorMessage(error));
72
+ }
73
+ export async function ensureServicesDomainInstalled(opts) {
74
+ const identityArgs = opts.identityArgs ?? [];
75
+ const target = `/${opts.servicesOrigin}`;
76
+ const probeArgs = [
77
+ 'ls',
78
+ target,
79
+ '-i',
80
+ opts.instance,
81
+ '--json',
82
+ '--timeout',
83
+ '60000',
84
+ ...identityArgs,
85
+ ];
86
+ try {
87
+ await opts.runAstrale(probeArgs);
88
+ return;
89
+ }
90
+ catch (error) {
91
+ opts.log(`services domain "${opts.servicesOrigin}" is not installed on "${opts.instance}" yet; installing it…`);
92
+ opts.log(` probe failed: ${errorMessage(error).slice(0, 220)}`);
93
+ }
94
+ await opts.runAstrale([
95
+ 'domain',
96
+ 'install',
97
+ opts.servicesOrigin,
98
+ '-i',
99
+ opts.instance,
100
+ '--json',
101
+ '--timeout',
102
+ '240000',
103
+ ...identityArgs,
104
+ ]);
105
+ await opts.runAstrale(probeArgs);
106
+ }
107
+ async function fetchJson(fetcher, url) {
108
+ const res = await fetcher(url, { signal: AbortSignal.timeout(MANAGED_READY_FETCH_TIMEOUT_MS) });
109
+ if (!res.ok)
110
+ throw new Error(`GET ${url} -> ${res.status}`);
111
+ return (await res.json());
112
+ }
113
+ function normalizeBaseUrl(url) {
114
+ return url.replace(/\/+$/, '');
115
+ }
116
+ function errorMessage(error) {
117
+ return error instanceof Error ? error.message : String(error);
118
+ }
119
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
120
+ //# sourceMappingURL=managed-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"managed-service.js","sourceRoot":"","sources":["../src/managed-service.ts"],"names":[],"mappings":"AAAA,MAAM,wBAAwB,GAAG,MAAM,CAAA;AACvC,MAAM,8BAA8B,GAAG,KAAK,CAAA;AAC5C,MAAM,sBAAsB,GAAG,KAAK,CAAA;AACpC,MAAM,wBAAwB,GAAG,CAAC,CAAA;AAgClC,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,GAAW,EACX,cAAsB,EACtB,IAAI,GAAwB,EAAE;IAE9B,MAAM,IAAI,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAA;IAClC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,IAAI,KAAK,CAAA;IACnC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,IAAI,KAAK,CAAA;IACnC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,sBAAsB,CAAA;IACtD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,wBAAwB,CAAA;IAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAA;IACvC,IAAI,UAAU,GAAG,EAAE,CAAA;IAEnB,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,MAAM,GAAG,aAAa,CAAA;QAC1B,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,SAAS,CAAc,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC,CAAA;YAClE,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;YAC/D,IAAI,IAAI,CAAC,UAAU,KAAK,cAAc,EAAE,CAAC;gBACvC,MAAM,GAAG,oBAAoB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,cAAc,EAAE,CAAA;YAC3F,CAAC;iBAAM,IAAI,IAAI,CAAC,kBAAkB,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAClF,MAAM,GAAG,oBAAoB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,IAAI,CAAC,kBAAkB,EAAE,CAAA;YACpG,CAAC;iBAAM,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;gBAC/B,MAAM,GAAG,aAAa,IAAI,CAAC,GAAG,aAAa,IAAI,EAAE,CAAA;YACnD,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,GAAG,MAAM,SAAS,CAC1B,OAAO,EACP,GAAG,UAAU,wBAAwB,CACtC,CAAA;gBACD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;gBACtD,IAAI,IAAI,CAAC,MAAM;oBAAE,OAAO,IAAI,CAAA;gBAC5B,MAAM,GAAG,uBAAuB,CAAA;YAClC,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;QAC9B,CAAC;QAED,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,EAAE,CAAC,4BAA4B,MAAM,EAAE,CAAC,CAAA;YAChD,UAAU,GAAG,MAAM,CAAA;QACrB,CAAC;QAED,MAAM,SAAS,GAAG,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACvC,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,yBAAyB,SAAS,OAAO,UAAU,EAAE,CAAC,CAAA;QAC/F,CAAC;QACD,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAA;IAC7C,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,GAAqB,EACrB,IAAI,GAA+B,EAAE;IAErC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,wBAAwB,CAAA;IAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,sBAAsB,CAAA;IACtD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,IAAI,KAAK,CAAA;IACnC,IAAI,SAAkB,CAAA;IAEtB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC;QACrD,IAAI,CAAC;YACH,OAAO,MAAM,GAAG,EAAE,CAAA;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,SAAS,GAAG,KAAK,CAAA;YACjB,IAAI,OAAO,IAAI,QAAQ,IAAI,CAAC,8BAA8B,CAAC,KAAK,CAAC;gBAAE,MAAM,KAAK,CAAA;YAC9E,IAAI,CAAC,GAAG,EAAE,CACR,qBAAqB,OAAO,IAAI,QAAQ,4BAA4B;gBAClE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,aAAa,CACpD,CAAA;YACD,MAAM,IAAI,CAAC,WAAW,EAAE,EAAE,CAAA;YAC1B,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;QACxB,CAAC;IACH,CAAC;IAED,MAAM,SAAS,YAAY,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAA;AAC7E,CAAC;AAED,MAAM,UAAU,8BAA8B,CAAC,KAAc;IAC3D,OAAO,wIAAwI,CAAC,IAAI,CAClJ,YAAY,CAAC,KAAK,CAAC,CACpB,CAAA;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,IAAiC;IAEjC,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,EAAE,CAAA;IAC5C,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,cAAc,EAAE,CAAA;IACxC,MAAM,SAAS,GAAG;QAChB,IAAI;QACJ,MAAM;QACN,IAAI;QACJ,IAAI,CAAC,QAAQ;QACb,QAAQ;QACR,WAAW;QACX,OAAO;QACP,GAAG,YAAY;KAChB,CAAA;IACD,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;QAChC,OAAM;IACR,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,GAAG,CACN,oBAAoB,IAAI,CAAC,cAAc,0BAA0B,IAAI,CAAC,QAAQ,uBAAuB,CACtG,CAAA;QACD,IAAI,CAAC,GAAG,CAAC,mBAAmB,YAAY,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;IAClE,CAAC;IAED,MAAM,IAAI,CAAC,UAAU,CAAC;QACpB,QAAQ;QACR,SAAS;QACT,IAAI,CAAC,cAAc;QACnB,IAAI;QACJ,IAAI,CAAC,QAAQ;QACb,QAAQ;QACR,WAAW;QACX,QAAQ;QACR,GAAG,YAAY;KAChB,CAAC,CAAA;IACF,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;AAClC,CAAC;AAED,KAAK,UAAU,SAAS,CAAI,OAAkB,EAAE,GAAW;IACzD,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,8BAA8B,CAAC,EAAE,CAAC,CAAA;IAC/F,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,OAAO,GAAG,OAAO,GAAG,CAAC,MAAM,EAAE,CAAC,CAAA;IAC3D,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAM,CAAA;AAChC,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAW;IACnC,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;AAChC,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC/D,CAAC;AAED,MAAM,KAAK,GAAY,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrale-os/adapter-astrale",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Deploy an Astrale domain as a managed service through the Astrale platform",
5
5
  "keywords": [
6
6
  "adapter",
@@ -27,8 +27,8 @@
27
27
  "./package.json": "./package.json"
28
28
  },
29
29
  "dependencies": {
30
- "@astrale-os/sdk": "^0.1.7",
31
- "@astrale-os/adapter-cloudflare": "^0.2.0"
30
+ "@astrale-os/adapter-cloudflare": "^0.2.1",
31
+ "@astrale-os/sdk": "^0.1.10"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@astrale-os/ox": ">=0.1.0 <1.0.0",
package/src/astrale.ts CHANGED
@@ -18,14 +18,14 @@
18
18
  * account, no wrangler auth — the only credential is the author's Astrale
19
19
  * identity, supplied by the `astrale` CLI session this adapter shells out to.
20
20
  *
21
- * REQUIRES the `services` domain installed on the target instance. An instance
22
- * without it can't host managed deploys — `deploy` fails loud with that hint.
21
+ * Ensures the `services` domain is installed on the target instance before the
22
+ * build/deploy work starts; without it the instance cannot host managed deploys.
23
23
  *
24
24
  * `watch` is identical to the Cloudflare adapter's local dev (wrangler dev on
25
25
  * localhost) — managed deploys change WHERE the worker runs, not how you iterate.
26
26
  */
27
27
 
28
- import type { DomainAdapter } from '@astrale-os/sdk'
28
+ import type { DeployCtx, DomainAdapter } from '@astrale-os/sdk'
29
29
 
30
30
  // The shared Cloudflare-Workers build toolkit — the managed adapter ships the
31
31
  // SAME bundle the direct `cloudflare` adapter does, then routes it through the
@@ -46,6 +46,12 @@ import { join, relative } from 'node:path'
46
46
 
47
47
  import type { AstraleParams } from './params'
48
48
 
49
+ import {
50
+ ensureServicesDomainInstalled,
51
+ runManagedInstallWithRetry,
52
+ waitForManagedServiceReady,
53
+ } from './managed-service'
54
+
49
55
  const DEFAULT_PORT = 8787
50
56
  const DEFAULT_SERVICES_ORIGIN = 'services.astrale.ai'
51
57
 
@@ -106,6 +112,16 @@ export function astrale(envs: Record<string, AstraleParams>): DomainAdapter<Astr
106
112
  const servicesOrigin = params.servicesOrigin ?? DEFAULT_SERVICES_ORIGIN
107
113
  const name = params.name ?? serviceNameFor(ctx.domain.origin)
108
114
 
115
+ const runProjectAstrale = (args: string[]) =>
116
+ runAstrale(astraleBin(ctx.projectDir), ctx.projectDir, args)
117
+ await ensureServicesDomainInstalled({
118
+ runAstrale: runProjectAstrale,
119
+ instance,
120
+ servicesOrigin,
121
+ identityArgs: identityArgs(params),
122
+ log,
123
+ })
124
+
109
125
  // Build + pack the client SPA: the services worker serves it under /ui.
110
126
  let assetFiles: AssetFile[] = []
111
127
  if (ctx.clientDir) {
@@ -202,30 +218,50 @@ export function astrale(envs: Record<string, AstraleParams>): DomainAdapter<Astr
202
218
  for (const [key, value] of Object.entries(secrets)) {
203
219
  await astraleCall(ctx.projectDir, params, {
204
220
  instance,
205
- path: `/${servicesOrigin}/services/${name}/setSecret`,
221
+ // The service node is placed at the root (`/${serviceSlugFor(origin)}`),
222
+ // not under a `/services` folder.
223
+ path: `/${serviceSlugFor(ctx.domain.origin)}::setSecret`,
206
224
  data: { name: key, value },
207
225
  viaStdin: true,
208
226
  })
209
227
  }
210
228
  }
211
229
 
230
+ // Cloudflare's dispatch namespace can acknowledge a script before the
231
+ // public tenant host is consistently serving the new worker. Installing
232
+ // before `/meta` + JWKS are reachable turns that propagation window into a
233
+ // postInstall fetch abort and leaves partial graph state behind.
234
+ const expectedSchemaHash = await expectedSchemaHashForManagedUrl(ctx, url, log)
235
+ log(`waiting for managed service "${ctx.domain.origin}" at ${url}…`)
236
+ await waitForManagedServiceReady(url, ctx.domain.origin, { log, expectedSchemaHash })
237
+
212
238
  // 4. Install the domain on the instance from the hosted URL. The child
213
239
  // kernel fetches the signed bundle, verifies it, and runs its postInstall.
214
240
  // A managed deploy ALWAYS aliases identity — the domain's origin
215
241
  // (`ctx.domain.origin`) is served from the platform host (`…svc.<routing>`)
216
242
  // it never matches — so consent to the override is implicit and required.
217
243
  log(`installing "${ctx.domain.origin}" on "${instance}" from ${url}…`)
218
- await runAstrale(astraleBin(ctx.projectDir), ctx.projectDir, [
219
- 'instance',
220
- 'install',
221
- url,
222
- '-i',
223
- instance,
224
- '--allow-identity-override',
225
- '--json',
226
- '--timeout',
227
- '240000',
228
- ])
244
+ await runManagedInstallWithRetry(
245
+ () =>
246
+ runAstrale(astraleBin(ctx.projectDir), ctx.projectDir, [
247
+ 'domain',
248
+ 'install',
249
+ url,
250
+ '--direct',
251
+ '-i',
252
+ instance,
253
+ '--allow-identity-override',
254
+ '--json',
255
+ '--timeout',
256
+ '240000',
257
+ ...identityArgs(params),
258
+ ]),
259
+ {
260
+ log,
261
+ beforeRetry: () =>
262
+ waitForManagedServiceReady(url, ctx.domain.origin, { log, expectedSchemaHash }),
263
+ },
264
+ )
229
265
 
230
266
  return {
231
267
  url,
@@ -241,6 +277,27 @@ export function astrale(envs: Record<string, AstraleParams>): DomainAdapter<Astr
241
277
  })
242
278
  }
243
279
 
280
+ async function expectedSchemaHashForManagedUrl(
281
+ ctx: DeployCtx,
282
+ url: string,
283
+ log: (line: string) => void,
284
+ ): Promise<string | undefined> {
285
+ if (!ctx.schemaHashForUrl) return undefined
286
+ try {
287
+ return await ctx.schemaHashForUrl(url)
288
+ } catch (error) {
289
+ log(
290
+ `warning: could not compute expected schema hash for ${url}; ` +
291
+ `readiness will verify domain/JWKS only (${errorMessage(error)})`,
292
+ )
293
+ return undefined
294
+ }
295
+ }
296
+
297
+ function errorMessage(error: unknown): string {
298
+ return error instanceof Error ? error.message : String(error)
299
+ }
300
+
244
301
  type AssetFile = { path: string; contentBase64: string; contentType?: string }
245
302
 
246
303
  /** Serving MIME by file extension. The provider serves each asset with the type
@@ -335,7 +392,7 @@ async function astraleCall(
335
392
  // default. Target the instance (`-i`), not admin — the services domain lives
336
393
  // on the instance.
337
394
  const args = ['call', call.path, '-i', call.instance, '--json', '--timeout', '240000']
338
- if (params.identity) args.push('--as', params.identity)
395
+ args.push(...identityArgs(params))
339
396
  const payload = JSON.stringify(call.data)
340
397
  if (!call.viaStdin) args.push('--data', payload)
341
398
 
@@ -352,6 +409,10 @@ async function astraleCall(
352
409
  }
353
410
  }
354
411
 
412
+ function identityArgs(params: AstraleParams): string[] {
413
+ return params.identity ? ['--as', params.identity] : []
414
+ }
415
+
355
416
  /** Spawn the astrale CLI, feed optional stdin, return stdout+stderr. Throws on non-zero exit. */
356
417
  async function runAstrale(
357
418
  bin: string,
@@ -0,0 +1,172 @@
1
+ const MANAGED_READY_TIMEOUT_MS = 90_000
2
+ const MANAGED_READY_FETCH_TIMEOUT_MS = 5_000
3
+ const MANAGED_READY_RETRY_MS = 1_000
4
+ const MANAGED_INSTALL_ATTEMPTS = 3
5
+
6
+ type ManagedMeta = { domainName?: string; iss?: string; schemaHash?: string }
7
+ type JsonFetch = typeof fetch
8
+ type SleepFn = (ms: number) => Promise<void>
9
+ type RunAstrale = (args: string[]) => Promise<string>
10
+
11
+ type ManagedReadyOptions = {
12
+ timeoutMs?: number
13
+ retryMs?: number
14
+ expectedSchemaHash?: string
15
+ fetch?: JsonFetch
16
+ sleep?: SleepFn
17
+ log?: (line: string) => void
18
+ }
19
+
20
+ type ManagedInstallRetryOptions = {
21
+ attempts?: number
22
+ retryMs?: number
23
+ sleep?: SleepFn
24
+ log?: (line: string) => void
25
+ beforeRetry?: () => Promise<unknown>
26
+ }
27
+
28
+ type EnsureServicesDomainOptions = {
29
+ runAstrale: RunAstrale
30
+ instance: string
31
+ servicesOrigin: string
32
+ identityArgs?: string[]
33
+ log: (line: string) => void
34
+ }
35
+
36
+ export async function waitForManagedServiceReady(
37
+ url: string,
38
+ expectedDomain: string,
39
+ opts: ManagedReadyOptions = {},
40
+ ): Promise<ManagedMeta> {
41
+ const base = normalizeBaseUrl(url)
42
+ const fetcher = opts.fetch ?? fetch
43
+ const sleepFn = opts.sleep ?? sleep
44
+ const retryMs = opts.retryMs ?? MANAGED_READY_RETRY_MS
45
+ const timeoutMs = opts.timeoutMs ?? MANAGED_READY_TIMEOUT_MS
46
+ const deadline = Date.now() + timeoutMs
47
+ let lastReason = ''
48
+
49
+ while (true) {
50
+ let reason = 'not checked'
51
+ try {
52
+ const meta = await fetchJson<ManagedMeta>(fetcher, `${base}/meta`)
53
+ const metaIssuer = meta.iss ? normalizeBaseUrl(meta.iss) : base
54
+ if (meta.domainName !== expectedDomain) {
55
+ reason = `/meta domainName=${JSON.stringify(meta.domainName)} expected=${expectedDomain}`
56
+ } else if (opts.expectedSchemaHash && meta.schemaHash !== opts.expectedSchemaHash) {
57
+ reason = `/meta schemaHash=${JSON.stringify(meta.schemaHash)} expected=${opts.expectedSchemaHash}`
58
+ } else if (metaIssuer !== base) {
59
+ reason = `/meta iss=${meta.iss} expected=${base}`
60
+ } else {
61
+ const jwks = await fetchJson<{ keys?: unknown[] }>(
62
+ fetcher,
63
+ `${metaIssuer}/.well-known/jwks.json`,
64
+ )
65
+ const keys = Array.isArray(jwks.keys) ? jwks.keys : []
66
+ if (keys.length) return meta
67
+ reason = 'JWKS returned no keys'
68
+ }
69
+ } catch (error) {
70
+ reason = errorMessage(error)
71
+ }
72
+
73
+ if (reason !== lastReason) {
74
+ opts.log?.(` service not ready yet: ${reason}`)
75
+ lastReason = reason
76
+ }
77
+
78
+ const remaining = deadline - Date.now()
79
+ if (remaining <= 0) {
80
+ throw new Error(`managed service ${base} was not ready within ${timeoutMs}ms: ${lastReason}`)
81
+ }
82
+ await sleepFn(Math.min(retryMs, remaining))
83
+ }
84
+ }
85
+
86
+ export async function runManagedInstallWithRetry<T>(
87
+ run: () => Promise<T>,
88
+ opts: ManagedInstallRetryOptions = {},
89
+ ): Promise<T> {
90
+ const attempts = opts.attempts ?? MANAGED_INSTALL_ATTEMPTS
91
+ const retryMs = opts.retryMs ?? MANAGED_READY_RETRY_MS
92
+ const sleepFn = opts.sleep ?? sleep
93
+ let lastError: unknown
94
+
95
+ for (let attempt = 1; attempt <= attempts; attempt++) {
96
+ try {
97
+ return await run()
98
+ } catch (error) {
99
+ lastError = error
100
+ if (attempt >= attempts || !isTransientManagedInstallError(error)) throw error
101
+ opts.log?.(
102
+ ` install attempt ${attempt}/${attempts} hit a transient failure: ` +
103
+ `${errorMessage(error).slice(0, 220)}; retrying…`,
104
+ )
105
+ await opts.beforeRetry?.()
106
+ await sleepFn(retryMs)
107
+ }
108
+ }
109
+
110
+ throw lastError instanceof Error ? lastError : new Error(String(lastError))
111
+ }
112
+
113
+ export function isTransientManagedInstallError(error: unknown): boolean {
114
+ return /network fetch failed|operation was aborted|fetch failed|und_err|econnreset|etimedout|timeout|503|504|522|524|worker startup timed out/i.test(
115
+ errorMessage(error),
116
+ )
117
+ }
118
+
119
+ export async function ensureServicesDomainInstalled(
120
+ opts: EnsureServicesDomainOptions,
121
+ ): Promise<void> {
122
+ const identityArgs = opts.identityArgs ?? []
123
+ const target = `/${opts.servicesOrigin}`
124
+ const probeArgs = [
125
+ 'ls',
126
+ target,
127
+ '-i',
128
+ opts.instance,
129
+ '--json',
130
+ '--timeout',
131
+ '60000',
132
+ ...identityArgs,
133
+ ]
134
+ try {
135
+ await opts.runAstrale(probeArgs)
136
+ return
137
+ } catch (error) {
138
+ opts.log(
139
+ `services domain "${opts.servicesOrigin}" is not installed on "${opts.instance}" yet; installing it…`,
140
+ )
141
+ opts.log(` probe failed: ${errorMessage(error).slice(0, 220)}`)
142
+ }
143
+
144
+ await opts.runAstrale([
145
+ 'domain',
146
+ 'install',
147
+ opts.servicesOrigin,
148
+ '-i',
149
+ opts.instance,
150
+ '--json',
151
+ '--timeout',
152
+ '240000',
153
+ ...identityArgs,
154
+ ])
155
+ await opts.runAstrale(probeArgs)
156
+ }
157
+
158
+ async function fetchJson<T>(fetcher: JsonFetch, url: string): Promise<T> {
159
+ const res = await fetcher(url, { signal: AbortSignal.timeout(MANAGED_READY_FETCH_TIMEOUT_MS) })
160
+ if (!res.ok) throw new Error(`GET ${url} -> ${res.status}`)
161
+ return (await res.json()) as T
162
+ }
163
+
164
+ function normalizeBaseUrl(url: string): string {
165
+ return url.replace(/\/+$/, '')
166
+ }
167
+
168
+ function errorMessage(error: unknown): string {
169
+ return error instanceof Error ? error.message : String(error)
170
+ }
171
+
172
+ const sleep: SleepFn = (ms) => new Promise((resolve) => setTimeout(resolve, ms))