@org-quicko/silo-client 1.0.0 → 1.1.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.
Files changed (46) hide show
  1. package/README.md +166 -124
  2. package/dist/collections/collection-handle.d.cts +15 -23
  3. package/dist/collections/collection-handle.d.ts +15 -23
  4. package/dist/collections/collections.d.cts +3 -5
  5. package/dist/collections/collections.d.ts +3 -5
  6. package/dist/entries/entry-envelope.d.cts +18 -0
  7. package/dist/entries/entry-envelope.d.ts +18 -0
  8. package/dist/entries/entry-read-options.d.cts +16 -0
  9. package/dist/entries/entry-read-options.d.ts +16 -0
  10. package/dist/entries/entry-reader.d.cts +16 -16
  11. package/dist/entries/entry-reader.d.ts +16 -16
  12. package/dist/entries/entry.d.cts +11 -23
  13. package/dist/entries/entry.d.ts +11 -23
  14. package/dist/errors/network-error.d.cts +5 -0
  15. package/dist/errors/network-error.d.ts +5 -0
  16. package/dist/index.cjs +87 -170
  17. package/dist/index.d.cts +4 -5
  18. package/dist/index.d.ts +4 -5
  19. package/dist/index.js +87 -170
  20. package/dist/media/media-asset.d.cts +17 -0
  21. package/dist/media/media-asset.d.ts +17 -0
  22. package/dist/media/media-file.d.cts +16 -0
  23. package/dist/media/media-file.d.ts +16 -0
  24. package/dist/media/media-replace.d.cts +17 -0
  25. package/dist/media/media-replace.d.ts +17 -0
  26. package/dist/media/media.d.cts +0 -4
  27. package/dist/media/media.d.ts +0 -4
  28. package/dist/search/search-hit.d.cts +5 -5
  29. package/dist/search/search-hit.d.ts +5 -5
  30. package/dist/search/search.d.cts +4 -1
  31. package/dist/search/search.d.ts +4 -1
  32. package/dist/transport/api-path.d.cts +1 -0
  33. package/dist/transport/api-path.d.ts +1 -0
  34. package/dist/transport/transport.d.cts +4 -0
  35. package/dist/transport/transport.d.ts +4 -0
  36. package/package.json +58 -58
  37. package/dist/collections/reserved-field-names.d.cts +0 -9
  38. package/dist/collections/reserved-field-names.d.ts +0 -9
  39. package/dist/entries/entry-base.d.cts +0 -31
  40. package/dist/entries/entry-base.d.ts +0 -31
  41. package/dist/entries/entry-mapper.d.cts +0 -13
  42. package/dist/entries/entry-mapper.d.ts +0 -13
  43. package/dist/entries/entry-payload.d.cts +0 -12
  44. package/dist/entries/entry-payload.d.ts +0 -12
  45. package/dist/entries/resolved-entry.d.cts +0 -11
  46. package/dist/entries/resolved-entry.d.ts +0 -11
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The four keys silo puts on every entry alongside the author's own fields.
3
+ *
4
+ * `rev` is here because `replace()` and `delete()` require the revision the
5
+ * caller expects and a mismatch is a `409`, so the number has to survive the
6
+ * trip from a read to a write. The timestamps are ISO-8601 strings rather than
7
+ * `Date`s, and `created_at` keeps the wire's spelling, because a row read from
8
+ * one call and handed to the next unchanged is worth more than a prettier one.
9
+ *
10
+ * No field can collide with these: silo refuses a schema declaring one and an
11
+ * entry carrying one (D62).
12
+ */
13
+ export interface EntryEnvelope {
14
+ id: string;
15
+ rev: number;
16
+ created_at: string;
17
+ updated_at: string;
18
+ }
@@ -0,0 +1,16 @@
1
+ import type { RequestOptions } from "../request-options.cjs";
2
+ /**
3
+ * What every read accepts on top of the cancellation options.
4
+ *
5
+ * `variables: "raw"` answers the `{{NAME}}` templates as stored instead of
6
+ * what they resolve to. An editor wants exactly that: seeding a form with a
7
+ * resolved value and saving it back replaces the reference somebody typed with
8
+ * a snapshot of what it meant in one environment on one day, and a template
9
+ * cannot be recovered from its substitution (D57).
10
+ *
11
+ * Reads resolve by default, because an application reading content should not
12
+ * have to opt in to a usable value.
13
+ */
14
+ export interface EntryReadOptions extends RequestOptions {
15
+ variables?: "raw";
16
+ }
@@ -0,0 +1,16 @@
1
+ import type { RequestOptions } from "../request-options.js";
2
+ /**
3
+ * What every read accepts on top of the cancellation options.
4
+ *
5
+ * `variables: "raw"` answers the `{{NAME}}` templates as stored instead of
6
+ * what they resolve to. An editor wants exactly that: seeding a form with a
7
+ * resolved value and saving it back replaces the reference somebody typed with
8
+ * a snapshot of what it meant in one environment on one day, and a template
9
+ * cannot be recovered from its substitution (D57).
10
+ *
11
+ * Reads resolve by default, because an application reading content should not
12
+ * have to opt in to a usable value.
13
+ */
14
+ export interface EntryReadOptions extends RequestOptions {
15
+ variables?: "raw";
16
+ }
@@ -1,26 +1,26 @@
1
- import type { RequestOptions } from "../request-options.cjs";
2
- import type { EntryContext } from "./entry-base.cjs";
1
+ import type { ScopeReference } from "../scope/scope-reference.cjs";
2
+ import type { Entry } from "./entry.cjs";
3
3
  import type { EntryListQuery } from "./entry-list-query.cjs";
4
4
  import { EntryPage } from "./entry-page.cjs";
5
5
  import { EntryPageStream } from "./entry-page-stream.cjs";
6
- import type { EntryPayload } from "./entry-payload.cjs";
6
+ import type { EntryReadOptions } from "./entry-read-options.cjs";
7
7
  import { EntryStream } from "./entry-stream.cjs";
8
8
  /**
9
- * Reads entries out of one collection and hands each answer to `wrap`.
9
+ * The four reads of one collection: one entry, one page, every entry, every
10
+ * page.
10
11
  *
11
- * A collection holds two: one asks for substituted values and answers
12
- * snapshots, the other asks for the stored templates and answers editable
13
- * entries. Both read the same routes, so the paging is written once here.
12
+ * Nothing is mapped on the way through an answer is the wire's own row
13
+ * (D62) so what this class actually owns is the paging the four share and
14
+ * the one place `variables` is turned into a query parameter.
14
15
  */
15
- export declare class EntryReader<Row> {
16
- private readonly context;
17
- private readonly variables;
18
- private readonly wrap;
19
- constructor(context: EntryContext, variables: "raw" | undefined, wrap: (payload: EntryPayload) => Row);
20
- get(id: string, options?: RequestOptions): Promise<Row>;
21
- list(query?: EntryListQuery, options?: RequestOptions): Promise<EntryPage<Row>>;
16
+ export declare class EntryReader<Fields> {
17
+ private readonly scope;
18
+ private readonly collection;
19
+ constructor(scope: ScopeReference, collection: string);
20
+ get(id: string, options?: EntryReadOptions): Promise<Entry<Fields>>;
21
+ list(query?: EntryListQuery, options?: EntryReadOptions): Promise<EntryPage<Entry<Fields>>>;
22
22
  /** Every matching entry, one at a time, `limit` rows per request. */
23
- all(query?: EntryListQuery, options?: RequestOptions): EntryStream<Row>;
23
+ all(query?: EntryListQuery, options?: EntryReadOptions): EntryStream<Entry<Fields>>;
24
24
  /** Every matching page, one at a time. */
25
- pages(query?: EntryListQuery, options?: RequestOptions): EntryPageStream<Row>;
25
+ pages(query?: EntryListQuery, options?: EntryReadOptions): EntryPageStream<Entry<Fields>>;
26
26
  }
@@ -1,26 +1,26 @@
1
- import type { RequestOptions } from "../request-options.js";
2
- import type { EntryContext } from "./entry-base.js";
1
+ import type { ScopeReference } from "../scope/scope-reference.js";
2
+ import type { Entry } from "./entry.js";
3
3
  import type { EntryListQuery } from "./entry-list-query.js";
4
4
  import { EntryPage } from "./entry-page.js";
5
5
  import { EntryPageStream } from "./entry-page-stream.js";
6
- import type { EntryPayload } from "./entry-payload.js";
6
+ import type { EntryReadOptions } from "./entry-read-options.js";
7
7
  import { EntryStream } from "./entry-stream.js";
8
8
  /**
9
- * Reads entries out of one collection and hands each answer to `wrap`.
9
+ * The four reads of one collection: one entry, one page, every entry, every
10
+ * page.
10
11
  *
11
- * A collection holds two: one asks for substituted values and answers
12
- * snapshots, the other asks for the stored templates and answers editable
13
- * entries. Both read the same routes, so the paging is written once here.
12
+ * Nothing is mapped on the way through an answer is the wire's own row
13
+ * (D62) so what this class actually owns is the paging the four share and
14
+ * the one place `variables` is turned into a query parameter.
14
15
  */
15
- export declare class EntryReader<Row> {
16
- private readonly context;
17
- private readonly variables;
18
- private readonly wrap;
19
- constructor(context: EntryContext, variables: "raw" | undefined, wrap: (payload: EntryPayload) => Row);
20
- get(id: string, options?: RequestOptions): Promise<Row>;
21
- list(query?: EntryListQuery, options?: RequestOptions): Promise<EntryPage<Row>>;
16
+ export declare class EntryReader<Fields> {
17
+ private readonly scope;
18
+ private readonly collection;
19
+ constructor(scope: ScopeReference, collection: string);
20
+ get(id: string, options?: EntryReadOptions): Promise<Entry<Fields>>;
21
+ list(query?: EntryListQuery, options?: EntryReadOptions): Promise<EntryPage<Entry<Fields>>>;
22
22
  /** Every matching entry, one at a time, `limit` rows per request. */
23
- all(query?: EntryListQuery, options?: RequestOptions): EntryStream<Row>;
23
+ all(query?: EntryListQuery, options?: EntryReadOptions): EntryStream<Entry<Fields>>;
24
24
  /** Every matching page, one at a time. */
25
- pages(query?: EntryListQuery, options?: RequestOptions): EntryPageStream<Row>;
25
+ pages(query?: EntryListQuery, options?: EntryReadOptions): EntryPageStream<Entry<Fields>>;
26
26
  }
@@ -1,25 +1,13 @@
1
- import type { RequestOptions } from "../request-options.cjs";
2
- import { ResolvedEntry } from "./resolved-entry.cjs";
1
+ import type { EntryEnvelope } from "./entry-envelope.cjs";
3
2
  /**
4
- * An editable entry, from a raw read: `posts.edit(id)`, a create, a
5
- * replace, or any read on a client constructed with `variables: "raw"`.
6
- * `fields` is mutable again here, undoing `ResolvedEntry`'s narrowing.
3
+ * One entry exactly as the API answers it: the author's fields and the
4
+ * envelope in one flat object, with nothing renamed, nested or wrapped.
5
+ *
6
+ * This is a plain value. It carries no transport, no scope and no methods, so
7
+ * it logs as its own contents, survives `structuredClone`, and drops into a
8
+ * store or React state as-is. Writes go through the collection —
9
+ * `posts.replace(id, rev, fields)`, `posts.delete(id, rev)` — where the
10
+ * revision being sent is visible at the call site instead of hidden inside an
11
+ * object (D62).
7
12
  */
8
- export declare class Entry<Fields> extends ResolvedEntry<Fields> {
9
- rev: number;
10
- createdAt: Date;
11
- updatedAt: Date;
12
- fields: Fields;
13
- private saving;
14
- /**
15
- * Sends `PUT` with the rev this instance holds, adopts the rev and
16
- * timestamps the response answers, and mutates in place. A second
17
- * overlapping call on the same instance is refused locally — it would
18
- * send a rev already known to be stale.
19
- */
20
- save(options?: RequestOptions): Promise<this>;
21
- /** Re-reads this entry raw, and replaces `fields`, `rev` and the
22
- * timestamps in place — what a `ConflictError` from `save()` calls for. */
23
- refresh(options?: RequestOptions): Promise<this>;
24
- private adopt;
25
- }
13
+ export type Entry<Fields = Record<string, unknown>> = Fields & EntryEnvelope;
@@ -1,25 +1,13 @@
1
- import type { RequestOptions } from "../request-options.js";
2
- import { ResolvedEntry } from "./resolved-entry.js";
1
+ import type { EntryEnvelope } from "./entry-envelope.js";
3
2
  /**
4
- * An editable entry, from a raw read: `posts.edit(id)`, a create, a
5
- * replace, or any read on a client constructed with `variables: "raw"`.
6
- * `fields` is mutable again here, undoing `ResolvedEntry`'s narrowing.
3
+ * One entry exactly as the API answers it: the author's fields and the
4
+ * envelope in one flat object, with nothing renamed, nested or wrapped.
5
+ *
6
+ * This is a plain value. It carries no transport, no scope and no methods, so
7
+ * it logs as its own contents, survives `structuredClone`, and drops into a
8
+ * store or React state as-is. Writes go through the collection —
9
+ * `posts.replace(id, rev, fields)`, `posts.delete(id, rev)` — where the
10
+ * revision being sent is visible at the call site instead of hidden inside an
11
+ * object (D62).
7
12
  */
8
- export declare class Entry<Fields> extends ResolvedEntry<Fields> {
9
- rev: number;
10
- createdAt: Date;
11
- updatedAt: Date;
12
- fields: Fields;
13
- private saving;
14
- /**
15
- * Sends `PUT` with the rev this instance holds, adopts the rev and
16
- * timestamps the response answers, and mutates in place. A second
17
- * overlapping call on the same instance is refused locally — it would
18
- * send a rev already known to be stale.
19
- */
20
- save(options?: RequestOptions): Promise<this>;
21
- /** Re-reads this entry raw, and replaces `fields`, `rev` and the
22
- * timestamps in place — what a `ConflictError` from `save()` calls for. */
23
- refresh(options?: RequestOptions): Promise<this>;
24
- private adopt;
25
- }
13
+ export type Entry<Fields = Record<string, unknown>> = Fields & EntryEnvelope;
@@ -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
  }