tablinum 0.1.1 → 0.2.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 (58) hide show
  1. package/README.md +124 -1
  2. package/dist/brands.d.ts +5 -0
  3. package/dist/crud/collection-handle.d.ts +5 -5
  4. package/dist/crud/query-builder.d.ts +4 -13
  5. package/dist/crud/watch.d.ts +0 -10
  6. package/dist/db/create-tablinum.d.ts +7 -0
  7. package/dist/db/database-handle.d.ts +22 -1
  8. package/dist/db/epoch.d.ts +48 -0
  9. package/dist/db/invite.d.ts +8 -0
  10. package/dist/db/key-rotation.d.ts +24 -0
  11. package/dist/db/members.d.ts +24 -0
  12. package/dist/db/runtime-config.d.ts +16 -0
  13. package/dist/index.d.ts +8 -1
  14. package/dist/index.js +1552 -820
  15. package/dist/layers/EpochStoreLive.d.ts +6 -0
  16. package/dist/layers/GiftWrapLive.d.ts +5 -0
  17. package/dist/layers/IdentityLive.d.ts +5 -0
  18. package/dist/layers/PublishQueueLive.d.ts +5 -0
  19. package/dist/layers/RelayLive.d.ts +3 -0
  20. package/dist/layers/StorageLive.d.ts +4 -0
  21. package/dist/layers/SyncStatusLive.d.ts +3 -0
  22. package/dist/layers/TablinumLive.d.ts +5 -0
  23. package/dist/layers/index.d.ts +8 -0
  24. package/dist/schema/field.d.ts +0 -1
  25. package/dist/schema/types.d.ts +0 -4
  26. package/dist/services/Config.d.ts +16 -0
  27. package/dist/services/EpochStore.d.ts +6 -0
  28. package/dist/services/GiftWrap.d.ts +6 -0
  29. package/dist/services/Identity.d.ts +6 -0
  30. package/dist/services/PublishQueue.d.ts +6 -0
  31. package/dist/services/Relay.d.ts +6 -0
  32. package/dist/services/Storage.d.ts +6 -0
  33. package/dist/services/Sync.d.ts +6 -0
  34. package/dist/services/SyncStatus.d.ts +6 -0
  35. package/dist/services/Tablinum.d.ts +7 -0
  36. package/dist/services/index.d.ts +10 -0
  37. package/dist/storage/idb.d.ts +11 -2
  38. package/dist/storage/lww.d.ts +0 -5
  39. package/dist/storage/records-store.d.ts +0 -7
  40. package/dist/svelte/collection.svelte.d.ts +9 -6
  41. package/dist/svelte/deferred.d.ts +7 -0
  42. package/dist/svelte/index.svelte.d.ts +6 -6
  43. package/dist/svelte/index.svelte.js +1881 -1023
  44. package/dist/svelte/query.svelte.d.ts +6 -6
  45. package/dist/svelte/tablinum.svelte.d.ts +35 -0
  46. package/dist/sync/gift-wrap.d.ts +6 -2
  47. package/dist/sync/negentropy.d.ts +1 -1
  48. package/dist/sync/publish-queue.d.ts +3 -2
  49. package/dist/sync/relay.d.ts +9 -2
  50. package/dist/sync/sync-service.d.ts +5 -2
  51. package/dist/sync/sync-status.d.ts +1 -0
  52. package/dist/utils/uuid.d.ts +0 -1
  53. package/package.json +1 -1
  54. package/dist/main.d.ts +0 -1
  55. package/dist/storage/events-store.d.ts +0 -6
  56. package/dist/storage/giftwraps-store.d.ts +0 -6
  57. package/dist/svelte/database.svelte.d.ts +0 -15
  58. package/dist/svelte/live-query.svelte.d.ts +0 -8
package/README.md CHANGED
@@ -60,7 +60,7 @@ const program = Effect.gen(function* () {
60
60
  const todo = yield* todos.get(id);
61
61
 
62
62
  // Query
63
- const pending = yield* todos.where("done").equals(false).toArray();
63
+ const pending = yield* todos.where("done").equals(false).get();
64
64
 
65
65
  // Update
66
66
  yield* todos.update(id, { done: true });
@@ -72,6 +72,129 @@ const program = Effect.gen(function* () {
72
72
  Effect.runPromise(Effect.scoped(program));
73
73
  ```
74
74
 
75
+ ## Svelte 5
76
+
77
+ Import from `tablinum/svelte` for reactive bindings that use Svelte 5 runes. No Effect knowledge needed — the API is plain async/await.
78
+
79
+ This API uses Svelte's async runes support, so enable it in your app config:
80
+
81
+ ```js
82
+ // svelte.config.js
83
+ const config = {
84
+ compilerOptions: {
85
+ experimental: {
86
+ async: true,
87
+ },
88
+ },
89
+ };
90
+ ```
91
+
92
+ ### Setup
93
+
94
+ Create a database helper that defines your schema and initializes the database:
95
+
96
+ ```typescript
97
+ // src/lib/db.ts
98
+ import { Tablinum, collection, field } from "tablinum/svelte";
99
+
100
+ const schema = {
101
+ todos: collection(
102
+ "todos",
103
+ {
104
+ title: field.string(),
105
+ done: field.boolean(),
106
+ },
107
+ { indices: ["done"] },
108
+ ),
109
+ };
110
+
111
+ export type AppSchema = typeof schema;
112
+
113
+ export const db = new Tablinum({
114
+ schema,
115
+ relays: ["wss://relay.example.com"],
116
+ });
117
+
118
+ export const todos = db.collection("todos");
119
+ ```
120
+
121
+ ### Component
122
+
123
+ Async collection reads are reactive when used inside `$derived(await ...)` expressions.
124
+
125
+ ```svelte
126
+ <script lang="ts">
127
+ import { db, todos } from "$lib/db";
128
+
129
+ let title = $state("");
130
+ let booted = $derived(await db.ready.then(() => true, () => false));
131
+ let pending = $derived(
132
+ booted && db.status === "ready"
133
+ ? await todos.where("done").equals(false).get()
134
+ : [],
135
+ );
136
+
137
+ async function addTodo(e: SubmitEvent) {
138
+ e.preventDefault();
139
+ if (!title.trim()) return;
140
+ await todos.add({ title: title.trim(), done: false });
141
+ title = "";
142
+ }
143
+
144
+ async function toggle(id: string, currentDone: boolean) {
145
+ await todos.update(id, { done: !currentDone });
146
+ }
147
+
148
+ async function remove(id: string) {
149
+ await todos.delete(id);
150
+ }
151
+ </script>
152
+
153
+ <svelte:boundary>
154
+ {#snippet pending()}
155
+ <p>Initializing database...</p>
156
+ {/snippet}
157
+
158
+ {#if db.status === "error"}
159
+ <p>{db.error?.message}</p>
160
+ {:else}
161
+ <p>{pending.length} pending</p>
162
+
163
+ <form onsubmit={addTodo}>
164
+ <input bind:value={title} placeholder="Add a todo..." />
165
+ <button type="submit">Add</button>
166
+ </form>
167
+
168
+ <ul>
169
+ {#each pending as todo (todo.id)}
170
+ <li>
171
+ <input
172
+ type="checkbox"
173
+ checked={todo.done}
174
+ onchange={() => toggle(todo.id, todo.done)}
175
+ />
176
+ <span>{todo.title}</span>
177
+ <button onclick={() => remove(todo.id)}>Delete</button>
178
+ </li>
179
+ {/each}
180
+ </ul>
181
+
182
+ {#if db.syncStatus === "syncing"}
183
+ <p>Syncing...</p>
184
+ {/if}
185
+
186
+ <button onclick={() => db.sync()}>Sync</button>
187
+ {/if}
188
+ </svelte:boundary>
189
+ ```
190
+
191
+ ### Key concepts
192
+
193
+ - **`new Tablinum(config)`** starts initialization immediately and exposes `db.ready`
194
+ - **Async queries are reactive** when used inside `$derived(await ...)`
195
+ - **`db.status`** tracks initialization and terminal state; **`db.syncStatus`** tracks sync activity
196
+ - **`createTablinum(config)`** still exists as a convenience and resolves once `db.ready` completes
197
+
75
198
  ## License
76
199
 
77
200
  MIT
@@ -0,0 +1,5 @@
1
+ import { Brand } from "effect";
2
+ export type EpochId = Brand.Branded<string, "EpochId">;
3
+ export declare const EpochId: Brand.Constructor<EpochId>;
4
+ export type DatabaseName = Brand.Branded<string, "DatabaseName">;
5
+ export declare const DatabaseName: Brand.Constructor<DatabaseName>;
@@ -1,21 +1,21 @@
1
- import { Effect, Stream } from "effect";
1
+ import { Effect, Option, Stream } from "effect";
2
2
  import type { CollectionDef, CollectionFields } from "../schema/collection.ts";
3
3
  import type { InferRecord } from "../schema/types.ts";
4
4
  import type { RecordValidator, PartialValidator } from "../schema/validate.ts";
5
5
  import type { IDBStorageHandle, StoredEvent } from "../storage/idb.ts";
6
6
  import { NotFoundError, StorageError, ValidationError } from "../errors.ts";
7
7
  import type { WatchContext } from "./watch.ts";
8
- import type { WhereClause, OrderByBuilder } from "./query-builder.ts";
8
+ import type { WhereClause, QueryBuilder } from "./query-builder.ts";
9
9
  export interface CollectionHandle<C extends CollectionDef<CollectionFields>> {
10
10
  readonly add: (data: Omit<InferRecord<C>, "id">) => Effect.Effect<string, ValidationError | StorageError>;
11
11
  readonly update: (id: string, data: Partial<Omit<InferRecord<C>, "id">>) => Effect.Effect<void, ValidationError | StorageError | NotFoundError>;
12
12
  readonly delete: (id: string) => Effect.Effect<void, StorageError | NotFoundError>;
13
13
  readonly get: (id: string) => Effect.Effect<InferRecord<C>, StorageError | NotFoundError>;
14
- readonly first: () => Effect.Effect<InferRecord<C> | null, StorageError>;
14
+ readonly first: () => Effect.Effect<Option.Option<InferRecord<C>>, StorageError>;
15
15
  readonly count: () => Effect.Effect<number, StorageError>;
16
16
  readonly watch: () => Stream.Stream<ReadonlyArray<InferRecord<C>>, StorageError>;
17
17
  readonly where: (field: string & keyof Omit<InferRecord<C>, "id">) => WhereClause<InferRecord<C>>;
18
- readonly orderBy: (field: string & keyof Omit<InferRecord<C>, "id">) => OrderByBuilder<InferRecord<C>>;
18
+ readonly orderBy: (field: string & keyof Omit<InferRecord<C>, "id">) => QueryBuilder<InferRecord<C>>;
19
19
  }
20
- export type OnWriteCallback = (event: StoredEvent) => Effect.Effect<void>;
20
+ export type OnWriteCallback = (event: StoredEvent) => Effect.Effect<void, StorageError>;
21
21
  export declare function createCollectionHandle<C extends CollectionDef<CollectionFields>>(def: C, storage: IDBStorageHandle, watchCtx: WatchContext, validator: RecordValidator<C["fields"]>, partialValidator: PartialValidator<C["fields"]>, makeEventId: () => string, onWrite?: OnWriteCallback): CollectionHandle<C>;
@@ -1,4 +1,4 @@
1
- import { Effect, Stream } from "effect";
1
+ import { Effect, Option, Stream } from "effect";
2
2
  import type { IDBStorageHandle } from "../storage/idb.ts";
3
3
  import type { StorageError, ValidationError } from "../errors.ts";
4
4
  import type { CollectionDef, CollectionFields } from "../schema/collection.ts";
@@ -24,19 +24,10 @@ export interface QueryBuilder<T> {
24
24
  readonly offset: (n: number) => QueryBuilder<T>;
25
25
  readonly limit: (n: number) => QueryBuilder<T>;
26
26
  readonly get: () => Effect.Effect<ReadonlyArray<T>, StorageError | ValidationError>;
27
- readonly first: () => Effect.Effect<T | null, StorageError | ValidationError>;
27
+ readonly first: () => Effect.Effect<Option.Option<T>, StorageError | ValidationError>;
28
28
  readonly count: () => Effect.Effect<number, StorageError | ValidationError>;
29
29
  readonly watch: () => Stream.Stream<ReadonlyArray<T>, StorageError | ValidationError>;
30
30
  }
31
- export interface OrderByBuilder<T> {
32
- readonly reverse: () => OrderByBuilder<T>;
33
- readonly offset: (n: number) => OrderByBuilder<T>;
34
- readonly limit: (n: number) => OrderByBuilder<T>;
35
- readonly get: () => Effect.Effect<ReadonlyArray<T>, StorageError | ValidationError>;
36
- readonly first: () => Effect.Effect<T | null, StorageError | ValidationError>;
37
- readonly count: () => Effect.Effect<number, StorageError | ValidationError>;
38
- readonly watch: () => Stream.Stream<ReadonlyArray<T>, StorageError | ValidationError>;
39
- }
40
- export type QueryExecutor<T> = QueryBuilder<T>;
31
+ export type OrderByBuilder<T> = QueryBuilder<T>;
41
32
  export declare function createWhereClause<T>(storage: IDBStorageHandle, watchCtx: WatchContext, collectionName: string, def: CollectionDef<CollectionFields>, fieldName: string, mapRecord: (record: Record<string, unknown>) => T): WhereClause<T>;
42
- export declare function createOrderByBuilder<T>(storage: IDBStorageHandle, watchCtx: WatchContext, collectionName: string, def: CollectionDef<CollectionFields>, fieldName: string, mapRecord: (record: Record<string, unknown>) => T): OrderByBuilder<T>;
33
+ export declare function createOrderByBuilder<T>(storage: IDBStorageHandle, watchCtx: WatchContext, collectionName: string, def: CollectionDef<CollectionFields>, fieldName: string, mapRecord: (record: Record<string, unknown>) => T): QueryBuilder<T>;
@@ -10,16 +10,6 @@ export interface WatchContext {
10
10
  readonly pubsub: PubSub.PubSub<ChangeEvent>;
11
11
  readonly replayingRef: Ref.Ref<boolean>;
12
12
  }
13
- /**
14
- * Create a reactive Stream that emits the current result set whenever it changes.
15
- */
16
13
  export declare function watchCollection<T>(ctx: WatchContext, storage: IDBStorageHandle, collectionName: string, filter?: (record: Record<string, unknown>) => boolean, mapRecord?: (record: Record<string, unknown>) => T): Stream.Stream<ReadonlyArray<T>, StorageError>;
17
- /**
18
- * Notify subscribers of a change.
19
- */
20
14
  export declare function notifyChange(ctx: WatchContext, event: ChangeEvent): Effect.Effect<void>;
21
- /**
22
- * Emit a replay-complete notification for all collections that changed.
23
- * Call after sync replay to trigger batched watch updates.
24
- */
25
15
  export declare function notifyReplayComplete(ctx: WatchContext, collections: ReadonlyArray<string>): Effect.Effect<void>;
@@ -1,12 +1,19 @@
1
1
  import { Effect, Scope } from "effect";
2
2
  import type { SchemaConfig } from "../schema/types.ts";
3
3
  import type { DatabaseHandle } from "./database-handle.ts";
4
+ import type { EpochKeyInput } from "./epoch.ts";
4
5
  import { CryptoError, StorageError, ValidationError } from "../errors.ts";
5
6
  export interface TablinumConfig<S extends SchemaConfig> {
6
7
  readonly schema: S;
7
8
  readonly relays: readonly string[];
8
9
  readonly privateKey?: Uint8Array | undefined;
10
+ readonly epochKeys?: ReadonlyArray<EpochKeyInput> | undefined;
9
11
  readonly dbName?: string | undefined;
10
12
  readonly onSyncError?: ((error: Error) => void) | undefined;
13
+ readonly onRemoved?: ((info: {
14
+ epochId: string;
15
+ removedBy: string;
16
+ }) => void) | undefined;
17
+ readonly onMembersChanged?: (() => void) | undefined;
11
18
  }
12
19
  export declare function createTablinum<S extends SchemaConfig>(config: TablinumConfig<S>): Effect.Effect<DatabaseHandle<S>, ValidationError | StorageError | CryptoError, Scope.Scope>;
@@ -1,13 +1,34 @@
1
1
  import type { Effect } from "effect";
2
+ import type { CollectionDef, CollectionFields } from "../schema/collection.ts";
2
3
  import type { CollectionHandle } from "../crud/collection-handle.ts";
3
4
  import type { SchemaConfig } from "../schema/types.ts";
4
- import type { StorageError, SyncError, RelayError, CryptoError } from "../errors.ts";
5
+ import type { StorageError, SyncError, RelayError, CryptoError, ValidationError } from "../errors.ts";
6
+ import type { Invite } from "./invite.ts";
7
+ import type { MemberRecord } from "./members.ts";
8
+ import type { RelayStatus } from "../sync/relay.ts";
5
9
  export type SyncStatus = "idle" | "syncing";
6
10
  export interface DatabaseHandle<S extends SchemaConfig> {
7
11
  readonly collection: <K extends string & keyof S>(name: K) => CollectionHandle<S[K]>;
12
+ readonly publicKey: string;
13
+ readonly members: CollectionHandle<CollectionDef<CollectionFields>>;
8
14
  readonly exportKey: () => string;
15
+ readonly exportInvite: () => Invite;
9
16
  readonly close: () => Effect.Effect<void, StorageError>;
10
17
  readonly rebuild: () => Effect.Effect<void, StorageError>;
11
18
  readonly sync: () => Effect.Effect<void, SyncError | RelayError | CryptoError | StorageError>;
12
19
  readonly getSyncStatus: () => Effect.Effect<SyncStatus>;
20
+ readonly subscribeSyncStatus: (callback: (status: SyncStatus) => void) => () => void;
21
+ readonly pendingCount: () => Effect.Effect<number>;
22
+ readonly subscribePendingCount: (callback: (count: number) => void) => () => void;
23
+ readonly getRelayStatus: () => RelayStatus;
24
+ readonly subscribeRelayStatus: (callback: (status: RelayStatus) => void) => () => void;
25
+ readonly addMember: (pubkey: string) => Effect.Effect<void, ValidationError | StorageError | CryptoError>;
26
+ readonly removeMember: (pubkey: string) => Effect.Effect<void, ValidationError | StorageError | SyncError | RelayError | CryptoError>;
27
+ readonly getMembers: () => Effect.Effect<ReadonlyArray<MemberRecord>, StorageError>;
28
+ readonly setProfile: (profile: {
29
+ name?: string;
30
+ picture?: string;
31
+ about?: string;
32
+ nip05?: string;
33
+ }) => Effect.Effect<void, ValidationError | StorageError | CryptoError>;
13
34
  }
@@ -0,0 +1,48 @@
1
+ import { Option, Schema } from "effect";
2
+ import { bytesToHex, hexToBytes } from "@noble/hashes/utils.js";
3
+ import { EpochId, DatabaseName } from "../brands.ts";
4
+ export { EpochId, DatabaseName };
5
+ export { bytesToHex, hexToBytes };
6
+ export interface EpochKeyInput {
7
+ readonly epochId: EpochId;
8
+ readonly key: string;
9
+ }
10
+ export interface EpochKey {
11
+ readonly id: EpochId;
12
+ readonly privateKey: string;
13
+ readonly publicKey: string;
14
+ readonly createdBy: string;
15
+ readonly parentEpoch?: EpochId;
16
+ }
17
+ export interface EpochStore {
18
+ readonly epochs: Map<EpochId, EpochKey>;
19
+ readonly keysByPublicKey: Map<string, Uint8Array>;
20
+ currentEpochId: EpochId;
21
+ }
22
+ export declare const EpochKeyInputSchema: Schema.Struct<{
23
+ readonly epochId: Schema.String;
24
+ readonly key: Schema.String;
25
+ }>;
26
+ interface EpochStoreSnapshot {
27
+ readonly epochs: ReadonlyArray<{
28
+ readonly id: string;
29
+ readonly privateKey: string;
30
+ readonly createdBy: string;
31
+ readonly parentEpoch?: string;
32
+ }>;
33
+ readonly currentEpochId: string;
34
+ }
35
+ export declare function createEpochKey(id: EpochId, privateKeyHex: string, createdBy: string, parentEpoch?: EpochId): EpochKey;
36
+ export declare function createEpochStore(initialEpoch: EpochKey): EpochStore;
37
+ export declare function addEpoch(store: EpochStore, epoch: EpochKey): void;
38
+ export declare function hydrateEpochStore(snapshot: EpochStoreSnapshot): EpochStore;
39
+ export declare function createEpochStoreFromInputs(epochKeys: ReadonlyArray<EpochKeyInput>, options?: {
40
+ readonly createdBy?: string | undefined;
41
+ }): EpochStore;
42
+ export declare function getCurrentEpoch(store: EpochStore): EpochKey;
43
+ export declare function getCurrentPublicKey(store: EpochStore): string;
44
+ export declare function getAllPublicKeys(store: EpochStore): string[];
45
+ export declare function getDecryptionKey(store: EpochStore, publicKey: string): Uint8Array | undefined;
46
+ export declare function exportEpochKeys(store: EpochStore): ReadonlyArray<EpochKeyInput>;
47
+ export declare function stringifyEpochStore(store: EpochStore): string;
48
+ export declare function deserializeEpochStore(raw: string): Option.Option<EpochStore>;
@@ -0,0 +1,8 @@
1
+ import { DatabaseName, type EpochKeyInput } from "./epoch.ts";
2
+ export interface Invite {
3
+ readonly epochKeys: Array<EpochKeyInput>;
4
+ readonly relays: string[];
5
+ readonly dbName: DatabaseName;
6
+ }
7
+ export declare function encodeInvite(invite: Invite): string;
8
+ export declare function decodeInvite(encoded: string): Invite;
@@ -0,0 +1,24 @@
1
+ import { Option } from "effect";
2
+ import type { NostrEvent } from "nostr-tools/pure";
3
+ import type { EpochKey, EpochStore } from "./epoch.ts";
4
+ import { EpochId } from "./epoch.ts";
5
+ export interface RotationResult {
6
+ readonly epoch: EpochKey;
7
+ readonly wrappedEvents: NostrEvent[];
8
+ readonly removalNotices: NostrEvent[];
9
+ }
10
+ export interface RotationData {
11
+ readonly _rotation: true;
12
+ readonly epochId: EpochId;
13
+ readonly epochKey: string;
14
+ readonly parentEpoch: EpochId;
15
+ readonly removedMembers: readonly string[];
16
+ }
17
+ export interface RemovalNotice {
18
+ readonly _removed: true;
19
+ readonly epochId: EpochId;
20
+ readonly removedBy: string;
21
+ }
22
+ export declare function createRotation(epochStore: EpochStore, senderPrivateKey: Uint8Array, senderPublicKey: string, remainingMemberPubkeys: string[], removedMemberPubkeys: string[]): RotationResult;
23
+ export declare function parseRotationEvent(content: string, dTag: string): Option.Option<RotationData>;
24
+ export declare function parseRemovalNotice(content: string, dTag: string): Option.Option<RemovalNotice>;
@@ -0,0 +1,24 @@
1
+ import { Effect, Option } from "effect";
2
+ import type { CollectionDef } from "../schema/collection.ts";
3
+ import type { RelayHandle } from "../sync/relay.ts";
4
+ import { RelayError } from "../errors.ts";
5
+ import type { EpochId } from "../brands.ts";
6
+ export interface MemberRecord {
7
+ readonly id: string;
8
+ readonly name?: string;
9
+ readonly picture?: string;
10
+ readonly about?: string;
11
+ readonly nip05?: string;
12
+ readonly addedAt: number;
13
+ readonly addedInEpoch: EpochId;
14
+ readonly removedAt?: number;
15
+ readonly removedInEpoch?: EpochId;
16
+ }
17
+ export interface AuthorProfile {
18
+ readonly name?: string;
19
+ readonly picture?: string;
20
+ readonly about?: string;
21
+ readonly nip05?: string;
22
+ }
23
+ export declare const membersCollectionDef: CollectionDef;
24
+ export declare function fetchAuthorProfile(relay: RelayHandle, relayUrls: readonly string[], pubkey: string): Effect.Effect<Option.Option<AuthorProfile>, RelayError>;
@@ -0,0 +1,16 @@
1
+ import { Effect } from "effect";
2
+ import { ValidationError } from "../errors.ts";
3
+ import { type EpochKeyInput, DatabaseName } from "./epoch.ts";
4
+ export interface RuntimeConfigSource {
5
+ readonly relays: readonly string[];
6
+ readonly privateKey?: Uint8Array | undefined;
7
+ readonly epochKeys?: ReadonlyArray<EpochKeyInput> | undefined;
8
+ readonly dbName?: string | undefined;
9
+ }
10
+ export interface ResolvedRuntimeConfig {
11
+ readonly relays: readonly string[];
12
+ readonly privateKey?: Uint8Array | undefined;
13
+ readonly epochKeys?: ReadonlyArray<EpochKeyInput> | undefined;
14
+ readonly dbName: DatabaseName;
15
+ }
16
+ export declare function resolveRuntimeConfig(source: RuntimeConfigSource): Effect.Effect<ResolvedRuntimeConfig, ValidationError>;
package/dist/index.d.ts CHANGED
@@ -6,7 +6,14 @@ export type { InferRecord, SchemaConfig } from "./schema/types.ts";
6
6
  export { createTablinum } from "./db/create-tablinum.ts";
7
7
  export type { TablinumConfig } from "./db/create-tablinum.ts";
8
8
  export type { DatabaseHandle, SyncStatus } from "./db/database-handle.ts";
9
+ export { encodeInvite, decodeInvite } from "./db/invite.ts";
10
+ export type { Invite } from "./db/invite.ts";
11
+ export { EpochId, DatabaseName } from "./brands.ts";
12
+ export type { EpochKey, EpochKeyInput } from "./db/epoch.ts";
13
+ export type { MemberRecord } from "./db/members.ts";
9
14
  export type { CollectionHandle } from "./crud/collection-handle.ts";
10
15
  export type { CollectionOptions } from "./schema/collection.ts";
11
- export type { WhereClause, QueryBuilder, OrderByBuilder, QueryExecutor, } from "./crud/query-builder.ts";
16
+ export type { WhereClause, QueryBuilder, OrderByBuilder } from "./crud/query-builder.ts";
17
+ export { TablinumLive } from "./layers/TablinumLive.ts";
18
+ export type { TablinumConfigShape } from "./services/Config.ts";
12
19
  export { ValidationError, StorageError, CryptoError, RelayError, SyncError, NotFoundError, ClosedError, } from "./errors.ts";