@lumavox/server 0.0.0-stage → 0.2.1

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.
Files changed (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +134 -2
  3. package/dist/client.d.ts +59 -0
  4. package/dist/client.js +52 -0
  5. package/dist/errors.d.ts +86 -0
  6. package/dist/errors.js +137 -0
  7. package/dist/gen/index.d.ts +1 -0
  8. package/dist/gen/index.js +2 -0
  9. package/dist/gen/types.gen.d.ts +6563 -0
  10. package/dist/gen/types.gen.js +2 -0
  11. package/dist/index.d.ts +23 -0
  12. package/dist/index.js +8 -0
  13. package/dist/paging.d.ts +34 -0
  14. package/dist/paging.js +41 -0
  15. package/dist/refuse.d.ts +11 -0
  16. package/dist/refuse.js +12 -0
  17. package/dist/resources/agents.d.ts +34 -0
  18. package/dist/resources/agents.js +33 -0
  19. package/dist/resources/assets.d.ts +59 -0
  20. package/dist/resources/assets.js +80 -0
  21. package/dist/resources/end-users.d.ts +73 -0
  22. package/dist/resources/end-users.js +139 -0
  23. package/dist/resources/ephemeral-keys.d.ts +65 -0
  24. package/dist/resources/ephemeral-keys.js +129 -0
  25. package/dist/resources/generations.d.ts +40 -0
  26. package/dist/resources/generations.js +55 -0
  27. package/dist/resources/knowledge.d.ts +58 -0
  28. package/dist/resources/knowledge.js +91 -0
  29. package/dist/resources/resource.d.ts +52 -0
  30. package/dist/resources/resource.js +68 -0
  31. package/dist/resources/speech.d.ts +80 -0
  32. package/dist/resources/speech.js +64 -0
  33. package/dist/resources/templates.d.ts +37 -0
  34. package/dist/resources/templates.js +50 -0
  35. package/dist/resources/usage.d.ts +15 -0
  36. package/dist/resources/usage.js +16 -0
  37. package/dist/resources/voices.d.ts +41 -0
  38. package/dist/resources/voices.js +53 -0
  39. package/dist/runtime.d.ts +22 -0
  40. package/dist/runtime.js +24 -0
  41. package/dist/stream.d.ts +6 -0
  42. package/dist/stream.js +37 -0
  43. package/dist/transport.d.ts +79 -0
  44. package/dist/transport.js +215 -0
  45. package/dist/upload.d.ts +37 -0
  46. package/dist/upload.js +34 -0
  47. package/dist/wait.d.ts +42 -0
  48. package/dist/wait.js +51 -0
  49. package/package.json +50 -4
package/dist/upload.js ADDED
@@ -0,0 +1,34 @@
1
+ /** The data's size, when it can be told without reading it. */
2
+ export const sizeOf = (data, size) => size ??
3
+ (data instanceof ReadableStream
4
+ ? undefined
5
+ : data instanceof Blob
6
+ ? data.size
7
+ : data.byteLength);
8
+ /** The data's type: the caller's, or a Blob's own; `""` when neither says. */
9
+ export const typeOf = (data, type) => type || (data instanceof Blob ? data.type : "");
10
+ /** `type`, or a `TypeError` naming what to pass. */
11
+ export function needType(data, type) {
12
+ const found = typeOf(data, type);
13
+ if (!found)
14
+ throw new TypeError("This upload needs its content_type.");
15
+ return found;
16
+ }
17
+ /** The bytes, to a ticket's signed URL, valid for its `expires_in` seconds. */
18
+ export async function put(api, ticket, data, type, options) {
19
+ let raw = data;
20
+ const headers = {};
21
+ if (data instanceof ReadableStream) {
22
+ const size = options.size;
23
+ if (size === undefined) {
24
+ throw new TypeError("A stream uploads only with its size: { size }.");
25
+ }
26
+ headers["Content-Length"] = String(size);
27
+ // Workers' own class, read off the global: no other runtime has it,
28
+ // nor do the types a customer compiles against.
29
+ const { FixedLengthStream: Fixed } = globalThis;
30
+ if (Fixed)
31
+ raw = data.pipeThrough(new Fixed(size));
32
+ }
33
+ await api.request({ method: "PUT", path: ticket.url, raw, type, headers, open: true }, { ...options, timeoutMs: options.timeoutMs ?? ticket.expires_in * 1000 });
34
+ }
package/dist/wait.d.ts ADDED
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Waiting on a job: the API has no route for "a job" — each kind is read
3
+ * where it lives (a generation, a voice, an asset, a knowledge entry), and
4
+ * each says how it went in its `status`. `wait(id)` reads it until that
5
+ * status is no longer one of work in progress.
6
+ *
7
+ * - **One set of in-progress states for every kind**: a generation is
8
+ * `queued`, `submitted` or `running`, the rest `pending`, and a
9
+ * knowledge file or page `importing` before that — which the document
10
+ * does not list (left-overs #113; `STATUSES` in
11
+ * `apps/api/src/knowledge/service.ts`). Anything else — `succeeded`,
12
+ * `failed`, `moderated`, `ready`, or a state this release does not know
13
+ * — ends the wait, so a new one cannot hang a caller.
14
+ * - **It answers the last read, never throws for a failure**: a `failed`
15
+ * or `moderated` generation is refunded, and its `error` says why — the
16
+ * caller reads `status`, as the API's own docs say to.
17
+ * - **The polls**: 1 s, then ×1.5 each time, at most 10 s apart. The
18
+ * caller's `signal` ends the wait (`AbortSignal.timeout(…)` for a
19
+ * deadline); otherwise the job's own deadline does, which refunds what
20
+ * never reports (the API's `settlers.ts`).
21
+ * - **Its ceiling is the organisation's Durable Object, not a rate
22
+ * limit**: a poll is unmetered, so the per-minute window
23
+ * (`RATE_LIMIT_RPM`, the org's, which only metered routes count) never
24
+ * sees it (`admit` in `apps/api/src/org/object.ts`). Each poll is two
25
+ * calls on the org's DO — its admission and the read — so at the 10 s
26
+ * cap 2,500 waits at once are 500 calls a second, the DO's trigger in
27
+ * the root `CLAUDE.md`; in their first second, 250 are.
28
+ */
29
+ import { type RequestOptions } from "./transport.js";
30
+ /**
31
+ * A job as each kind's read answers it: with a `status` — which the
32
+ * document lets an asset and an entry leave out (it has a default), and
33
+ * which, absent, is no work in progress.
34
+ */
35
+ export interface Job {
36
+ status?: string;
37
+ }
38
+ /**
39
+ * Reads `read` until its status is final, starting from `first` (a job
40
+ * just made, so the first read waits) or with a read now.
41
+ */
42
+ export declare function poll<T extends Job>(read: () => Promise<T>, options?: RequestOptions, first?: T): Promise<T>;
package/dist/wait.js ADDED
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Waiting on a job: the API has no route for "a job" — each kind is read
3
+ * where it lives (a generation, a voice, an asset, a knowledge entry), and
4
+ * each says how it went in its `status`. `wait(id)` reads it until that
5
+ * status is no longer one of work in progress.
6
+ *
7
+ * - **One set of in-progress states for every kind**: a generation is
8
+ * `queued`, `submitted` or `running`, the rest `pending`, and a
9
+ * knowledge file or page `importing` before that — which the document
10
+ * does not list (left-overs #113; `STATUSES` in
11
+ * `apps/api/src/knowledge/service.ts`). Anything else — `succeeded`,
12
+ * `failed`, `moderated`, `ready`, or a state this release does not know
13
+ * — ends the wait, so a new one cannot hang a caller.
14
+ * - **It answers the last read, never throws for a failure**: a `failed`
15
+ * or `moderated` generation is refunded, and its `error` says why — the
16
+ * caller reads `status`, as the API's own docs say to.
17
+ * - **The polls**: 1 s, then ×1.5 each time, at most 10 s apart. The
18
+ * caller's `signal` ends the wait (`AbortSignal.timeout(…)` for a
19
+ * deadline); otherwise the job's own deadline does, which refunds what
20
+ * never reports (the API's `settlers.ts`).
21
+ * - **Its ceiling is the organisation's Durable Object, not a rate
22
+ * limit**: a poll is unmetered, so the per-minute window
23
+ * (`RATE_LIMIT_RPM`, the org's, which only metered routes count) never
24
+ * sees it (`admit` in `apps/api/src/org/object.ts`). Each poll is two
25
+ * calls on the org's DO — its admission and the read — so at the 10 s
26
+ * cap 2,500 waits at once are 500 calls a second, the DO's trigger in
27
+ * the root `CLAUDE.md`; in their first second, 250 are.
28
+ */
29
+ import { sleep } from "./transport.js";
30
+ const IN_PROGRESS = [
31
+ "queued",
32
+ "submitted",
33
+ "running",
34
+ "pending",
35
+ "importing",
36
+ ];
37
+ const FIRST_MS = 1_000;
38
+ const MAX_MS = 10_000;
39
+ /**
40
+ * Reads `read` until its status is final, starting from `first` (a job
41
+ * just made, so the first read waits) or with a read now.
42
+ */
43
+ export async function poll(read, options = {}, first) {
44
+ let job = first ?? (await read());
45
+ for (let ms = FIRST_MS; IN_PROGRESS.includes(job.status);) {
46
+ await sleep(ms, options.signal);
47
+ job = await read();
48
+ ms = Math.min(ms * 1.5, MAX_MS);
49
+ }
50
+ return job;
51
+ }
package/package.json CHANGED
@@ -1,6 +1,52 @@
1
1
  {
2
2
  "name": "@lumavox/server",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.2.1",
4
+ "description": "The Lumavox API from your server: end users, ephemeral keys and the rest, typed from the published OpenAPI document. Zero dependencies.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "engines": {
8
+ "node": ">=20.3.0"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "sideEffects": [
14
+ "./dist/refuse.js"
15
+ ],
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "workerd": "./dist/index.js",
20
+ "worker": "./dist/index.js",
21
+ "edge-light": "./dist/index.js",
22
+ "deno": "./dist/index.js",
23
+ "bun": "./dist/index.js",
24
+ "node": "./dist/index.js",
25
+ "react-native": "./dist/refuse.js",
26
+ "browser": "./dist/refuse.js",
27
+ "default": "./dist/index.js"
28
+ },
29
+ "./package.json": "./package.json"
30
+ },
31
+ "scripts": {
32
+ "generate": "openapi-ts",
33
+ "build": "node scripts/build.mjs",
34
+ "prepack": "node scripts/build.mjs",
35
+ "check": "biome check --write",
36
+ "format": "biome format --write",
37
+ "lint": "biome lint",
38
+ "test": "vitest run",
39
+ "test:unit": "vitest run",
40
+ "typecheck": "tsc --noEmit && tsc --noEmit -p test"
41
+ },
42
+ "devDependencies": {
43
+ "@biomejs/biome": "2.6.2",
44
+ "@cloudflare/vitest-plugin": "1.4.7",
45
+ "@cloudflare/workers-types": "^5.20261022.1",
46
+ "@hey-api/openapi-ts": "^0.99.0",
47
+ "@types/node": "^24",
48
+ "esbuild": "^0.28.1",
49
+ "typescript": "^6",
50
+ "vitest": "^4.1.12"
51
+ }
52
+ }