@nitida/sdk 0.28.0 → 0.29.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/AGENTS.md +1 -1
- package/LICENSE +21 -0
- package/README.md +16 -7
- package/SECURITY.md +56 -0
- package/dist/expo.d.ts +4 -4
- package/dist/expo.js +2 -2
- package/dist/expo.js.map +1 -1
- package/dist/index.d.ts +26 -2
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/dist/server.js +12 -2
- package/dist/server.js.map +1 -1
- package/dist/web.d.ts +1 -1
- package/dist/web.js +12 -2
- package/dist/web.js.map +1 -1
- package/package.json +7 -5
- package/skills/nitida-sdk/SKILL.md +3 -2
- package/src/expo/index.ts +5 -5
- package/src/index.ts +55 -5
- package/src/web/index.ts +3 -3
package/src/expo/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @nitida/sdk/expo — native multipart uploads for React Native / Expo.
|
|
3
3
|
*
|
|
4
|
-
* Wraps `@
|
|
4
|
+
* Wraps `@nitida/asset-uploader-expo`'s `UploadTask`, which delegates
|
|
5
5
|
* the actual byte transfer to a native background session (URLSession
|
|
6
6
|
* on iOS, WorkManager on Android). The upload survives:
|
|
7
7
|
* - JS thread freezing
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
* is not built. It is the same gap `/web` documents. Ask; there is no public
|
|
54
54
|
* tracker.
|
|
55
55
|
*
|
|
56
|
-
* Peer dep: `@
|
|
56
|
+
* Peer dep: `@nitida/asset-uploader-expo` (lazy — apps that don't
|
|
57
57
|
* use the mobile SDK skip the install).
|
|
58
58
|
* @module @nitida/sdk/expo
|
|
59
59
|
*/
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
import {
|
|
62
62
|
UploadTask,
|
|
63
63
|
type UploadTaskOptions,
|
|
64
|
-
} from "@
|
|
64
|
+
} from "@nitida/asset-uploader-expo";
|
|
65
65
|
import type { NitidaClient } from "..";
|
|
66
66
|
|
|
67
67
|
export type ExpoUploadOptions = Omit<
|
|
@@ -97,9 +97,9 @@ export type {
|
|
|
97
97
|
UploadFileInput,
|
|
98
98
|
UploadSessionState,
|
|
99
99
|
UploadTaskOptions,
|
|
100
|
-
} from "@
|
|
100
|
+
} from "@nitida/asset-uploader-expo";
|
|
101
101
|
export {
|
|
102
102
|
cancelResumableSession,
|
|
103
103
|
listResumableSessions,
|
|
104
104
|
UploadTask,
|
|
105
|
-
} from "@
|
|
105
|
+
} from "@nitida/asset-uploader-expo";
|
package/src/index.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* platform.
|
|
4
4
|
*
|
|
5
5
|
* One ergonomic facade over the underlying packages
|
|
6
|
-
* (`@nitida/asset-client` URL builders + `@
|
|
6
|
+
* (`@nitida/asset-client` URL builders + `@nitida/asset-uploader-web`
|
|
7
7
|
* + the slot resolver). Auth is a bearer API key (`amk_rt_*`), issued
|
|
8
8
|
* per tenant when the tenant is created; tenant scope comes from
|
|
9
9
|
* the key's metadata (`X-Tenant-Code` is log-only).
|
|
@@ -820,7 +820,49 @@ class AssetsApi {
|
|
|
820
820
|
* Default timeout is 5 minutes; videos / HLS ladders may need a
|
|
821
821
|
* higher cap (pass `10 * 60_000` for compositions, transcodes).
|
|
822
822
|
*/
|
|
823
|
-
async waitReady(
|
|
823
|
+
async waitReady(
|
|
824
|
+
assetId: string,
|
|
825
|
+
/**
|
|
826
|
+
* Milliseconds, OR `{ timeoutMs }`.
|
|
827
|
+
*
|
|
828
|
+
* ⭐ It accepts the object because that is what people write. Found
|
|
829
|
+
* 2026-08-23 while smoke-testing a brand-new tenant: I passed
|
|
830
|
+
* `{ timeoutMs: 90_000 }` — every other option-taking method in this SDK
|
|
831
|
+
* takes an object — and got
|
|
832
|
+
*
|
|
833
|
+
* Error: waitReady: no asset a379fbbb-…
|
|
834
|
+
*
|
|
835
|
+
* about an asset that existed, was `ready`, and whose variants were all
|
|
836
|
+
* serving 200. `Date.now() - start < {…}` compares against NaN, so the
|
|
837
|
+
* loop body never ran, `last` stayed null, and the message blamed the one
|
|
838
|
+
* thing that was fine.
|
|
839
|
+
*
|
|
840
|
+
* TypeScript catches the wrong shape. Running it through `bun` does not —
|
|
841
|
+
* the same gap that let `upload()`'s `sha256` reach a URL builder wanting
|
|
842
|
+
* `sha` and produce `.../undefined.webp`. The lesson there was the same as
|
|
843
|
+
* here: a guard with a good message is still a mistake the user has to
|
|
844
|
+
* make first. Make the obvious call correct instead.
|
|
845
|
+
*/
|
|
846
|
+
timeout: number | { timeoutMs?: number } = 5 * 60_000,
|
|
847
|
+
): Promise<AssetDTO> {
|
|
848
|
+
// A string, a Date, anything else: refuse it. Falling back to the default
|
|
849
|
+
// would be the same silent-success this whole method just stopped doing —
|
|
850
|
+
// `waitReady(id, "90s")` would wait five minutes and the caller would
|
|
851
|
+
// never learn why.
|
|
852
|
+
const timeoutMs =
|
|
853
|
+
typeof timeout === "number"
|
|
854
|
+
? timeout
|
|
855
|
+
: timeout !== null && typeof timeout === "object"
|
|
856
|
+
? (timeout.timeoutMs ?? 5 * 60_000)
|
|
857
|
+
: Number.NaN;
|
|
858
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
859
|
+
throw new Error(
|
|
860
|
+
"waitReady: timeout must be a positive number of milliseconds or " +
|
|
861
|
+
`{ timeoutMs }, got ${JSON.stringify(timeout)}. A non-numeric ` +
|
|
862
|
+
"timeout makes the poll loop exit before its first iteration, which " +
|
|
863
|
+
`used to surface as "no asset <id>" about an asset that was fine.`,
|
|
864
|
+
);
|
|
865
|
+
}
|
|
824
866
|
const start = Date.now();
|
|
825
867
|
let delay = 500;
|
|
826
868
|
let last: AssetDTO | null = null;
|
|
@@ -830,7 +872,15 @@ class AssetsApi {
|
|
|
830
872
|
await new Promise((r) => setTimeout(r, delay));
|
|
831
873
|
delay = Math.min(delay * 1.5, 5_000);
|
|
832
874
|
}
|
|
833
|
-
|
|
875
|
+
// Unreachable now that a non-numeric timeout is refused above: any
|
|
876
|
+
// positive timeout runs the loop at least once, so `last` is set. Kept as
|
|
877
|
+
// a belt, with a message that no longer accuses the asset of not existing.
|
|
878
|
+
if (!last) {
|
|
879
|
+
throw new Error(
|
|
880
|
+
`waitReady: polled ${assetId} zero times in ${timeoutMs}ms — this is a ` +
|
|
881
|
+
"bug in the SDK, not a missing asset.",
|
|
882
|
+
);
|
|
883
|
+
}
|
|
834
884
|
throw new Error(`waitReady timeout for ${assetId}`);
|
|
835
885
|
}
|
|
836
886
|
|
|
@@ -1545,10 +1595,10 @@ export class NitidaClient {
|
|
|
1545
1595
|
// was not enough: `bun build --compile` constant-folds simple
|
|
1546
1596
|
// strings and still eagerly bundled `./web.js`, which
|
|
1547
1597
|
// top-level-imports the browser-only peer deps
|
|
1548
|
-
// `@
|
|
1598
|
+
// `@nitida/asset-uploader-web` / `@nitida/asset-compressor-web`
|
|
1549
1599
|
// — neither installed on server consumers — crashing the
|
|
1550
1600
|
// single-binary on boot with `Cannot find module
|
|
1551
|
-
// '@
|
|
1601
|
+
// '@nitida/asset-uploader-web'`.
|
|
1552
1602
|
//
|
|
1553
1603
|
// The earlier `new URL("./web.js", import.meta.url)` + `await import(URL)`
|
|
1554
1604
|
// dance survived bun-compile but Turbopack still tracks the URL literal
|
package/src/web/index.ts
CHANGED
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
* `apiKey` and bundles cleanly only in Node/Bun/edge runtimes.
|
|
45
45
|
*
|
|
46
46
|
* Peer deps (auto-installed via npm peer deps — declared optional):
|
|
47
|
-
* - `@
|
|
47
|
+
* - `@nitida/asset-uploader-web` for multipart uploads
|
|
48
48
|
* - `@nitida/asset-compressor-web` for client-side compression
|
|
49
49
|
*
|
|
50
50
|
* Both are lazy-imported; bundles that never call into them skip the cost.
|
|
@@ -197,7 +197,7 @@ export {
|
|
|
197
197
|
|
|
198
198
|
// Multipart uploader helpers are NOT re-exported from this subpath.
|
|
199
199
|
//
|
|
200
|
-
// `@
|
|
200
|
+
// `@nitida/asset-uploader-web` is an optional peer-dep that isn't on
|
|
201
201
|
// npm yet, so a static `import` at module top broke every consumer of
|
|
202
202
|
// `@nitida/sdk/web` (the bundler tries to resolve before the optional
|
|
203
203
|
// peer check kicks in). The old `createWebUploader` + `UploadTask`
|
|
@@ -209,7 +209,7 @@ export {
|
|
|
209
209
|
// token is not exposed yet. Ask us; there is no public tracker.
|
|
210
210
|
//
|
|
211
211
|
// Apps that need `UploadTask` directly today should depend on
|
|
212
|
-
// `@
|
|
212
|
+
// `@nitida/asset-uploader-web` themselves once it's published.
|
|
213
213
|
|
|
214
214
|
// ---------------------------------------------------------------------------
|
|
215
215
|
// Client-side compression (Phase 1.5)
|