@org-quicko/silo-client 1.0.1 → 1.1.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.
- package/README.md +49 -1
- package/dist/cache/cache-mode.d.cts +2 -0
- package/dist/cache/cache-mode.d.ts +2 -0
- package/dist/cache/response-cache.d.cts +16 -0
- package/dist/cache/response-cache.d.ts +16 -0
- package/dist/cache/silo-cache-options.d.cts +7 -0
- package/dist/cache/silo-cache-options.d.ts +7 -0
- package/dist/cache/silo-cache.d.cts +11 -0
- package/dist/cache/silo-cache.d.ts +11 -0
- package/dist/errors/network-error.d.cts +5 -0
- package/dist/errors/network-error.d.ts +5 -0
- package/dist/index.cjs +264 -74
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +264 -74
- package/dist/media/media-asset.d.cts +17 -0
- package/dist/media/media-asset.d.ts +17 -0
- package/dist/media/media-file.d.cts +16 -0
- package/dist/media/media-file.d.ts +16 -0
- package/dist/media/media-page.d.cts +1 -0
- package/dist/media/media-page.d.ts +1 -0
- package/dist/media/media-replace.d.cts +17 -0
- package/dist/media/media-replace.d.ts +17 -0
- package/dist/media/media-usage-page.d.cts +1 -0
- package/dist/media/media-usage-page.d.ts +1 -0
- package/dist/media/media.d.cts +0 -4
- package/dist/media/media.d.ts +0 -4
- package/dist/request-options.d.cts +3 -0
- package/dist/request-options.d.ts +3 -0
- package/dist/silo-options.d.cts +4 -0
- package/dist/silo-options.d.ts +4 -0
- package/dist/silo.d.cts +3 -0
- package/dist/silo.d.ts +3 -0
- package/dist/transport/api-path.d.cts +1 -0
- package/dist/transport/api-path.d.ts +1 -0
- package/dist/transport/caching-transport.d.cts +14 -0
- package/dist/transport/caching-transport.d.ts +14 -0
- package/dist/transport/fetch-transport.d.cts +31 -0
- package/dist/transport/fetch-transport.d.ts +31 -0
- package/dist/transport/prepared-transport-request.d.cts +6 -0
- package/dist/transport/prepared-transport-request.d.ts +6 -0
- package/dist/transport/transport-request.d.cts +2 -0
- package/dist/transport/transport-request.d.ts +2 -0
- package/dist/transport/transport.d.cts +2 -39
- package/dist/transport/transport.d.ts +2 -39
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -8,7 +8,8 @@ an environment holds collections, and a collection holds entries.
|
|
|
8
8
|
npm install @org-quicko/silo-client
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
Runs on Node 18+, Bun, Deno, browsers and workers.
|
|
11
|
+
Runs on Node 18+, Bun, Deno, browsers and workers. Its optional cache uses one
|
|
12
|
+
runtime dependency, `@isaacs/ttlcache`.
|
|
12
13
|
|
|
13
14
|
The examples below build moviespace, a small film database.
|
|
14
15
|
|
|
@@ -208,6 +209,7 @@ value you store. Storing the URL instead is what a later rename breaks.
|
|
|
208
209
|
await poster.rename("arrival-2016.jpg")
|
|
209
210
|
await poster.moveTo("posters/2016")
|
|
210
211
|
await poster.setTags(["poster"]) // replaces the whole list
|
|
212
|
+
await poster.replace(file) // new bytes, same id, name and URL
|
|
211
213
|
await poster.delete() // refused while an entry refers to it
|
|
212
214
|
await poster.delete({ force: true })
|
|
213
215
|
|
|
@@ -217,6 +219,12 @@ usage.total // the true count
|
|
|
217
219
|
usage.visible // how many of them this key may see
|
|
218
220
|
```
|
|
219
221
|
|
|
222
|
+
`replace` swaps the file behind an asset. The id, the reference, the name and
|
|
223
|
+
the URL all stay, so every entry that refers to it shows the new file and none
|
|
224
|
+
of them is rewritten. The new file must keep the same extension. It needs the
|
|
225
|
+
`media:replace` claim, and `entries:update` on each scope that refers to the
|
|
226
|
+
asset.
|
|
227
|
+
|
|
220
228
|
Folders, and a bulk delete that takes up to 100 ids:
|
|
221
229
|
|
|
222
230
|
```ts
|
|
@@ -312,6 +320,46 @@ await movies.get(id, { timeoutMilliseconds: 2_000 })
|
|
|
312
320
|
Nothing is retried for you. A retried `POST` creates a second entry, and only
|
|
313
321
|
the caller knows whether a call was safe to repeat.
|
|
314
322
|
|
|
323
|
+
## Optional read cache
|
|
324
|
+
|
|
325
|
+
Reads go to the server unless you enable caching. Choose a positive finite
|
|
326
|
+
integer TTL in milliseconds. It starts when a response is stored and does
|
|
327
|
+
not reset on a hit. `maxEntries` is optional; set it to bound memory use in a
|
|
328
|
+
long-running client. When full, the soonest-expiring entry is removed first.
|
|
329
|
+
|
|
330
|
+
```ts
|
|
331
|
+
const silo = new Silo({
|
|
332
|
+
url: "https://cms.moviespace.com",
|
|
333
|
+
cache: { ttlMilliseconds: 5_000, maxEntries: 100 },
|
|
334
|
+
})
|
|
335
|
+
const movies = silo.scope("moviespace", "prod").collection<Movie>("movies")
|
|
336
|
+
|
|
337
|
+
await movies.get(id) // may use a cached response
|
|
338
|
+
await movies.get(id, { cache: "bypass" }) // fetch without reading or storing
|
|
339
|
+
await movies.get(id, { cache: "refresh" }) // fetch and store on success
|
|
340
|
+
silo.cache.clear() // after a change made elsewhere
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
Only successful GET JSON responses are cached, with separate entries for
|
|
344
|
+
different URLs, queries and headers, including API keys. Returned objects
|
|
345
|
+
are independent copies. A failed refresh leaves the existing cache unchanged.
|
|
346
|
+
Your writes clear the shared cache before dispatch and after settlement,
|
|
347
|
+
including failures. Pending reads cannot refill it after a clear or overwrite
|
|
348
|
+
a newer read. `health()` always bypasses; `MediaAsset.refresh()` refreshes by
|
|
349
|
+
default and accepts an explicit bypass. Modes do nothing when caching is off.
|
|
350
|
+
|
|
351
|
+
`withKey()` and `withUrl()` share the cache. To share it explicitly, pass
|
|
352
|
+
`cache: otherClient.cache`, or construct `new SiloCache({ ttlMilliseconds: 5000 })`.
|
|
353
|
+
The facade exposes only `enabled`, `size` and `clear()`. Sharing preserves
|
|
354
|
+
isolation by URL and headers. If a custom fetch adds authentication or changes
|
|
355
|
+
the destination, include that context in the client's URL/headers or bypass
|
|
356
|
+
caching.
|
|
357
|
+
|
|
358
|
+
The cache lives in the tab, worker or process. Changes made elsewhere can
|
|
359
|
+
remain hidden until expiry or a fresh read. Infinite TTLs are unsupported;
|
|
360
|
+
`maxEntries` defaults to unlimited and may be `Infinity`. On Deno, an active
|
|
361
|
+
expiry timer can keep the process alive; call `clear()` when finished.
|
|
362
|
+
|
|
315
363
|
## Anonymous reads
|
|
316
364
|
|
|
317
365
|
A key is optional. Without one you reach the collections whose schema does not
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SiloCacheOptions } from "./silo-cache-options.cjs";
|
|
2
|
+
interface CachedResponse {
|
|
3
|
+
body: unknown;
|
|
4
|
+
}
|
|
5
|
+
/** The cache's values and pending-read tickets. */
|
|
6
|
+
export declare class ResponseCache {
|
|
7
|
+
#private;
|
|
8
|
+
constructor(options: SiloCacheOptions);
|
|
9
|
+
get size(): number;
|
|
10
|
+
get(key: string): CachedResponse | undefined;
|
|
11
|
+
set(key: string, ticket: symbol, body: unknown): void;
|
|
12
|
+
start(key: string): symbol;
|
|
13
|
+
finish(key: string, ticket: symbol): void;
|
|
14
|
+
clear(): void;
|
|
15
|
+
}
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SiloCacheOptions } from "./silo-cache-options.js";
|
|
2
|
+
interface CachedResponse {
|
|
3
|
+
body: unknown;
|
|
4
|
+
}
|
|
5
|
+
/** The cache's values and pending-read tickets. */
|
|
6
|
+
export declare class ResponseCache {
|
|
7
|
+
#private;
|
|
8
|
+
constructor(options: SiloCacheOptions);
|
|
9
|
+
get size(): number;
|
|
10
|
+
get(key: string): CachedResponse | undefined;
|
|
11
|
+
set(key: string, ticket: symbol, body: unknown): void;
|
|
12
|
+
start(key: string): symbol;
|
|
13
|
+
finish(key: string, ticket: symbol): void;
|
|
14
|
+
clear(): void;
|
|
15
|
+
}
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Bounds an opt-in in-memory read cache. */
|
|
2
|
+
export interface SiloCacheOptions {
|
|
3
|
+
/** Positive finite safe integer in milliseconds, counted from storage. */
|
|
4
|
+
ttlMilliseconds: number;
|
|
5
|
+
/** Positive safe integer or Infinity. Omit for no count limit. */
|
|
6
|
+
maxEntries?: number;
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Bounds an opt-in in-memory read cache. */
|
|
2
|
+
export interface SiloCacheOptions {
|
|
3
|
+
/** Positive finite safe integer in milliseconds, counted from storage. */
|
|
4
|
+
ttlMilliseconds: number;
|
|
5
|
+
/** Positive safe integer or Infinity. Omit for no count limit. */
|
|
6
|
+
maxEntries?: number;
|
|
7
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SiloCacheOptions } from "./silo-cache-options.cjs";
|
|
2
|
+
/** An optional, in-memory cache shared by one or more `Silo` instances. */
|
|
3
|
+
export declare class SiloCache {
|
|
4
|
+
#private;
|
|
5
|
+
constructor(options?: SiloCacheOptions);
|
|
6
|
+
get enabled(): boolean;
|
|
7
|
+
get size(): number;
|
|
8
|
+
/** Clears responses and prevents pending reads from storing their results. */
|
|
9
|
+
clear(): void;
|
|
10
|
+
private static validate;
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SiloCacheOptions } from "./silo-cache-options.js";
|
|
2
|
+
/** An optional, in-memory cache shared by one or more `Silo` instances. */
|
|
3
|
+
export declare class SiloCache {
|
|
4
|
+
#private;
|
|
5
|
+
constructor(options?: SiloCacheOptions);
|
|
6
|
+
get enabled(): boolean;
|
|
7
|
+
get size(): number;
|
|
8
|
+
/** Clears responses and prevents pending reads from storing their results. */
|
|
9
|
+
clear(): void;
|
|
10
|
+
private static validate;
|
|
11
|
+
}
|
|
@@ -8,4 +8,9 @@ export declare class NetworkError extends Error {
|
|
|
8
8
|
readonly method: string;
|
|
9
9
|
readonly path: string;
|
|
10
10
|
constructor(method: string, path: string, cause: unknown);
|
|
11
|
+
/** What `fetch` rejected with, in the message itself: a `cause` chain is
|
|
12
|
+
* printed by some consoles and by no log line, and "never reached the
|
|
13
|
+
* server" alone reads as a verdict on the network when the fault can be the
|
|
14
|
+
* call. */
|
|
15
|
+
private static reason;
|
|
11
16
|
}
|
|
@@ -8,4 +8,9 @@ export declare class NetworkError extends Error {
|
|
|
8
8
|
readonly method: string;
|
|
9
9
|
readonly path: string;
|
|
10
10
|
constructor(method: string, path: string, cause: unknown);
|
|
11
|
+
/** What `fetch` rejected with, in the message itself: a `cause` chain is
|
|
12
|
+
* printed by some consoles and by no log line, and "never reached the
|
|
13
|
+
* server" alone reads as a verdict on the network when the fault can be the
|
|
14
|
+
* call. */
|
|
15
|
+
private static reason;
|
|
11
16
|
}
|