@oddington/sdk 0.1.45 → 0.1.47
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 +79 -19
- package/dist/browser.js +273 -82
- package/dist/index.js +2 -2
- package/dist/types/packages/sdk/src/data-schema-types.d.ts +3 -3
- package/dist/types/shared/data-contract.d.ts +9 -22
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -246,13 +246,45 @@ try {
|
|
|
246
246
|
}
|
|
247
247
|
|
|
248
248
|
os.init({ auth: browserAuth }); // Trusted workspace host startup only.
|
|
249
|
-
// Later: await browserAuth.signOut(); // Ends
|
|
249
|
+
// Later: await browserAuth.signOut(); // Ends the active session.
|
|
250
250
|
// On document teardown (refresh, navigation or close):
|
|
251
251
|
unsubscribe();
|
|
252
252
|
browserAuth.dispose();
|
|
253
253
|
```
|
|
254
254
|
|
|
255
|
-
`
|
|
255
|
+
In a local app started by `os app dev` or `os app launch`, the same handle
|
|
256
|
+
uses the CLI-backed app connection and presents the signed-in viewer:
|
|
257
|
+
|
|
258
|
+
```ts
|
|
259
|
+
const { status, account } = browserAuth.getState();
|
|
260
|
+
if (status === "signed_in") {
|
|
261
|
+
// account.email and account.displayName identify this app's current viewer.
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Use this account for viewer-aware presentation such as a Mine filter. Subscribe
|
|
266
|
+
to keep that presentation current; it is not an authorization decision. There
|
|
267
|
+
is no Inbox identity call, extra hosted lookup, browser provider session or CLI
|
|
268
|
+
token. The handle and `os.init` share one exact-origin connection. Expiry clears
|
|
269
|
+
account presentation, and same-session renewal restores it. Local sign-out ends
|
|
270
|
+
the host session for its browsers; a failed confirmation reports unavailable.
|
|
271
|
+
Disposal preserves the connection's stored proofs for document refresh. Local
|
|
272
|
+
passcode and consent actions are unavailable: sign in with `os login` first.
|
|
273
|
+
|
|
274
|
+
In React, consume the handle as an external store so an early auth update cannot
|
|
275
|
+
be missed between rendering and subscribing:
|
|
276
|
+
|
|
277
|
+
```ts
|
|
278
|
+
import { useSyncExternalStore } from "react";
|
|
279
|
+
|
|
280
|
+
const authState = useSyncExternalStore(browserAuth.subscribe, browserAuth.getState);
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Derive viewer-aware UI from the current `authState.account`; account changes do
|
|
284
|
+
not require refetching the app's records.
|
|
285
|
+
|
|
286
|
+
At a hosted workspace origin, `auth.create()` accepts no options. Trusted
|
|
287
|
+
same-origin OS setup selects the
|
|
256
288
|
provider internally through exact-origin `GET /api/auth`, owned by OS. The SDK
|
|
257
289
|
uses same-origin credentials, refuses redirects and bypasses caching. Missing or
|
|
258
290
|
invalid setup makes authentication unavailable without a legacy endpoint or
|
|
@@ -652,9 +684,10 @@ external edits. Current local Data acquires no hosted binding or index. A dead
|
|
|
652
684
|
local parent fails without hosted fallback.
|
|
653
685
|
|
|
654
686
|
Each graph selection sends one request and returns only selected canonical
|
|
655
|
-
values, expanded forward links and exact opaque public versions.
|
|
656
|
-
continue
|
|
657
|
-
|
|
687
|
+
values, expanded forward links and exact opaque public versions. For selected current repositories, cursors
|
|
688
|
+
continue a live keyset position with the same selection; each page reads current.
|
|
689
|
+
Concurrent movement can repeat or skip a Record. Unselected repositories temporarily
|
|
690
|
+
retain their existing exact-version cursors. Repeat options and links while omitting completed collections.
|
|
658
691
|
There is no automatic retry or separate version fetch.
|
|
659
692
|
Collection schemas omit Markdown storage hints.
|
|
660
693
|
|
|
@@ -698,19 +731,22 @@ const matches = await general.records.all(query, { maxRecords: 10_000 });
|
|
|
698
731
|
|
|
699
732
|
Both helpers preserve literal collection arrays and selected-link inference.
|
|
700
733
|
`pages` captures the query at invocation, fetches only when requested, and never
|
|
701
|
-
prefetches after a consumer stops. Independent collection cursors
|
|
702
|
-
|
|
734
|
+
prefetches after a consumer stops. Independent collection cursors continue live positions; versions and requested
|
|
735
|
+
counts may change between pages. Completed collections yield empty arrays on later pages and retain
|
|
703
736
|
requested counts. Empty matches yield one versioned page. Helpers own continuation;
|
|
704
737
|
use `query` for a manual `after` cursor or explicit historical query.
|
|
705
738
|
|
|
706
|
-
`all`
|
|
739
|
+
`all` sends one bounded collection operation. Selected hosted execution uses one
|
|
740
|
+
ordinary database transaction, and local execution reads one captured in-memory
|
|
741
|
+
view. Records, requested counts and version describe that single observation;
|
|
742
|
+
the operation retains no snapshot afterward.
|
|
707
743
|
Its required positive safe-integer `maxRecords` caps top-level Record occurrences
|
|
708
744
|
across all collections; expanded links do not count toward that ceiling. Overflow
|
|
709
745
|
names the queried collections and ceiling, tells the author to narrow the query
|
|
710
746
|
or increase `maxRecords`, and rejects with nonretryable `capacity` without a
|
|
711
747
|
partial or truncated result.
|
|
712
748
|
Invalid helper arguments use `invalid_query`; malformed pages, cursor cycles,
|
|
713
|
-
|
|
749
|
+
or missing/invalid requested counts use nonretryable `unavailable`.
|
|
714
750
|
Query and authority failures propagate unchanged, with no retry or restart.
|
|
715
751
|
|
|
716
752
|
Read known stable refs directly, including refs from different collections:
|
|
@@ -789,7 +825,7 @@ sees completed Changes writes and external edits. Search Records supply captured
|
|
|
789
825
|
versions for subsequent Changes. Explicit History keeps its hosted contract.
|
|
790
826
|
|
|
791
827
|
`where` combines field conditions with AND. Alongside exact scalar/null equality
|
|
792
|
-
and `$in`, declared one-valued `integer`, `number` and `
|
|
828
|
+
and `$in`, declared one-valued `integer`, `number`, `date` and `datetime` fields accept
|
|
793
829
|
`$gt`, `$gte`, `$lt` and `$lte`:
|
|
794
830
|
|
|
795
831
|
```ts
|
|
@@ -808,6 +844,28 @@ A valid interval without matches returns an empty array and requested zero
|
|
|
808
844
|
count. V0 types check expression structure; runtime schema validation owns field
|
|
809
845
|
eligibility. Repeat the same bounds when continuing a cursor.
|
|
810
846
|
|
|
847
|
+
A `kind: datetime` field is an instant represented as a canonical UTC string
|
|
848
|
+
with milliseconds, for example `2026-09-15T14:30:00.000Z`. OS validates the real
|
|
849
|
+
date/time and exact `YYYY-MM-DDTHH:mm:ss.sssZ` spelling. Invalid dates, offsets,
|
|
850
|
+
missing or excess fractional digits and Date objects reject; values are never
|
|
851
|
+
silently converted or rounded. To convert an instant explicitly, use
|
|
852
|
+
`Date.toISOString()`. Returned values remain strings and equality/ranges/order
|
|
853
|
+
all use the same canonical representation. Existing string fields need an
|
|
854
|
+
explicit schema change to acquire datetime semantics.
|
|
855
|
+
|
|
856
|
+
The app owns business timezone boundaries. For September 2026 in Europe/London,
|
|
857
|
+
pass the UTC start (inclusive) and next-month start (exclusive):
|
|
858
|
+
|
|
859
|
+
```ts
|
|
860
|
+
await general.records.query({ emails: { $: { where: {
|
|
861
|
+
received_at: { $gte: '2026-08-31T23:00:00.000Z', $lt: '2026-09-30T23:00:00.000Z' },
|
|
862
|
+
}, order: { received_at: 'desc' } } } });
|
|
863
|
+
```
|
|
864
|
+
|
|
865
|
+
This filters metadata in the query engine before returning selected Records;
|
|
866
|
+
the app can then batch-read bodies only for those matches. A calendar `date`
|
|
867
|
+
continues to mean a day/month without a timezone.
|
|
868
|
+
|
|
811
869
|
`DataOperationError.code` distinguishes `context_unavailable`, `unauthenticated`,
|
|
812
870
|
`access_denied`, `invalid_query`, `request_too_large`, `capacity` and `unavailable`.
|
|
813
871
|
For reads, only `capacity` and `unavailable` are retryable; an error never includes private
|
|
@@ -835,7 +893,6 @@ schema fields, in the same guarded change:
|
|
|
835
893
|
changes.create({ $ref: 'emails/email-123', type: 'email', subject: 'Invoice',
|
|
836
894
|
$body: 'Hello,\n\nPlease find our invoice attached.\n' });
|
|
837
895
|
changes.update(existingEmail, { $body: revisedMarkdown }); // body-only change
|
|
838
|
-
const emails = await general.records.read(emailRefs, { body: true });
|
|
839
896
|
```
|
|
840
897
|
|
|
841
898
|
Omitted `$body` on create means empty; omitted on update preserves the existing
|
|
@@ -843,16 +900,19 @@ body exactly. A string deliberately replaces it, `''` clears it, and `null` is
|
|
|
843
900
|
invalid. Body-only edits preserve front matter, field-only edits preserve the
|
|
844
901
|
body, and both share the Record's exact-byte version guard. Bodies round-trip
|
|
845
902
|
without Markdown interpretation, formatting, trimming, or fence semantics.
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
903
|
+
Selections and search return structured fields only. Exact reads remain
|
|
904
|
+
body-free unless they explicitly request the body:
|
|
905
|
+
|
|
906
|
+
```ts
|
|
907
|
+
const email = await general.records.read('emails/email-123', { body: true });
|
|
908
|
+
console.log(email?.$body);
|
|
909
|
+
```
|
|
910
|
+
|
|
911
|
+
Local change batches support 32 MiB of serialized JSON; hosted requests retain
|
|
912
|
+
their separate 256 KiB limit.
|
|
852
913
|
|
|
853
914
|
The customer routine owns content and authoring policy. For imported emails,
|
|
854
|
-
create with the prepared body, omit `$body` on ordinary reruns, and
|
|
855
|
-
only bodies explicitly read as exactly empty. Existing notes and fenced blocks
|
|
915
|
+
create with the prepared body, omit `$body` on ordinary reruns, and preserve existing source bodies on ordinary reruns. Existing notes and fenced blocks
|
|
856
916
|
remain ordinary authored content. A fresh version alone does not authorize
|
|
857
917
|
overwriting an existing nonempty body.
|
|
858
918
|
|