@evolu/common 6.0.1-preview.15 → 6.0.1-preview.17

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.
@@ -465,36 +465,36 @@ export type EvoluDeps = CreateDbWorkerDep &
465
465
  ConsoleDep &
466
466
  CreateAppStateDep;
467
467
 
468
- export interface EvoluConfigWithInitialData<S extends EvoluSchema = EvoluSchema>
469
- extends Config {
468
+ export interface EvoluConfigWithFunctions extends Config {
470
469
  /**
471
- * Use this option to create initial data (fixtures).
470
+ * Callback invoked when the database is initialized. Use `isFirst` to perform
471
+ * one-time setup like initial data seeding.
472
472
  *
473
473
  * ### Example
474
474
  *
475
475
  * ```ts
476
476
  * const evolu = createEvolu(evoluReactWebDeps)(Schema, {
477
- * initialData: (evolu) => {
478
- * const todoCategory = evolu.insert("todoCategory", {
479
- * name: "Not Urgent",
480
- * });
477
+ * onInit: ({ appOwner, isFirst }) => {
478
+ * if (isFirst) {
479
+ * const todoCategoryId = getOrThrow(
480
+ * evolu.insert("todoCategory", {
481
+ * name: "Not Urgent",
482
+ * }),
483
+ * );
481
484
  *
482
- * // This is a developer error, which should be fixed immediately.
483
- * assert(todoCategory.ok, "invalid initial data");
484
- *
485
- * evolu.insert("todo", {
486
- * title: "Try React Suspense",
487
- * categoryId: todoCategory.value.id,
488
- * });
485
+ * evolu.insert("todo", {
486
+ * title: "Try React Suspense",
487
+ * categoryId: todoCategoryId.id,
488
+ * });
489
+ * }
489
490
  * },
490
491
  * });
491
492
  * ```
492
493
  */
493
- initialData?: (evolu: EvoluForInitialData<S>) => void;
494
- }
495
-
496
- export interface EvoluForInitialData<S extends EvoluSchema = EvoluSchema> {
497
- insert: Mutation<S, "insert">;
494
+ readonly onInit?: (params: {
495
+ readonly appOwner: AppOwner;
496
+ readonly isFirst: boolean;
497
+ }) => void;
498
498
  }
499
499
 
500
500
  // For hot reloading and Evolu multitenancy.
@@ -553,7 +553,7 @@ export const createEvolu =
553
553
  (deps: EvoluDeps) =>
554
554
  <S extends EvoluSchema>(
555
555
  schema: ValidateSchema<S> extends never ? S : ValidateSchema<S>,
556
- partialConfig: Partial<EvoluConfigWithInitialData<S>> = {},
556
+ partialConfig: Partial<EvoluConfigWithFunctions> = {},
557
557
  ): Evolu<S> => {
558
558
  const config = { ...defaultConfig, ...partialConfig };
559
559
 
@@ -577,17 +577,17 @@ const createEvoluInstance =
577
577
  (deps: EvoluDeps) =>
578
578
  (
579
579
  schema: EvoluSchema,
580
- evoluConfig: EvoluConfigWithInitialData,
580
+ evoluConfig: EvoluConfigWithFunctions,
581
581
  ): InternalEvoluInstance => {
582
582
  deps.console.enabled = evoluConfig.enableLogging ?? false;
583
583
 
584
584
  deps.console.log("[evolu]", "createEvoluInstance");
585
585
 
586
- const { initialData, indexes, ...config } = evoluConfig;
586
+ const { onInit, indexes, ...config } = evoluConfig;
587
587
 
588
588
  const errorStore = createStore<EvoluError | null>(null);
589
589
  const rowsStore = createStore<QueryRowsMap>(new Map());
590
- const ownerStore = createStore<AppOwner | null>(null);
590
+ const appOwnerStore = createStore<AppOwner | null>(null);
591
591
  const syncStore = createStore<SyncState>(initialSyncState);
592
592
 
593
593
  const subscribedQueries = createSubscribedQueries(rowsStore);
@@ -605,7 +605,11 @@ const createEvoluInstance =
605
605
  dbWorker.onMessage((message) => {
606
606
  switch (message.type) {
607
607
  case "onInit": {
608
- ownerStore.set(message.owner);
608
+ appOwnerStore.set(message.appOwner);
609
+ onInit?.({
610
+ appOwner: message.appOwner,
611
+ isFirst: message.isFirst,
612
+ });
609
613
  break;
610
614
  }
611
615
 
@@ -700,40 +704,10 @@ const createEvoluInstance =
700
704
  return type;
701
705
  };
702
706
 
703
- const initialDataDbChanges: Array<DbChange> = [];
704
-
705
- /**
706
- * Note that the initial data function is called even if it is unnecessary
707
- * (initial data are already in the DB) because we don't want to wait for
708
- * SQLite's response. Initial data should be small (because they are inlined
709
- * in the code), so it's ok.
710
- */
711
- if (initialData)
712
- initialData({
713
- insert: (table, props) => {
714
- const id = createId(deps);
715
- const values = getMutationType(table, "insert").fromUnknown(props);
716
-
717
- if (values.ok) {
718
- const valuesWithCreatedAt = {
719
- ...values.value,
720
- createdAt: new Date(deps.time.now()).toISOString(),
721
- };
722
- const dbChange = { table, id, values: valuesWithCreatedAt };
723
- assertValidDbChange(dbChange);
724
- initialDataDbChanges.push(dbChange);
725
- return ok({ id });
726
- }
727
-
728
- return values;
729
- },
730
- });
731
-
732
707
  dbWorker.postMessage({
733
708
  type: "init",
734
709
  config,
735
710
  dbSchema,
736
- initialData: initialDataDbChanges,
737
711
  });
738
712
 
739
713
  const loadQueryMicrotaskQueue: Array<Query> = [];
@@ -907,8 +881,8 @@ const createEvoluInstance =
907
881
  getQueryRows: <R extends Row>(query: Query<R>): QueryRows<R> =>
908
882
  (rowsStore.get().get(query) ?? emptyRows) as QueryRows<R>,
909
883
 
910
- subscribeAppOwner: ownerStore.subscribe,
911
- getAppOwner: ownerStore.get,
884
+ subscribeAppOwner: appOwnerStore.subscribe,
885
+ getAppOwner: appOwnerStore.get,
912
886
 
913
887
  subscribeSyncState: syncStore.subscribe,
914
888
  getSyncState: syncStore.get,
@@ -1,12 +1,36 @@
1
+ /* eslint-disable jsdoc/no-undefined-types */
1
2
  /**
2
- * TODO:
3
+ * Evolu Owner - Data Ownership and Collaboration
4
+ *
5
+ * An {@link Owner} is an entity that represents ownership of data in Evolu. It
6
+ * consists of cryptographic keys derived from a {@link Mnemonic} via SLIP-21:
7
+ *
8
+ * - **{@link OwnerId}**: Globally unique public identifier
9
+ * - **{@link EncryptionKey}**: Symmetric encryption key for data protection
10
+ * - **{@link WriteKey}**: Authentication token for write operations
11
+ *
12
+ * Every Evolu app has at least one owner, the {@link AppOwner}. There are
13
+ * several owner variants for different use cases:
14
+ *
15
+ * **{@link ShardOwner}**: Derived from {@link AppOwner} for partitioning data and
16
+ * selective synchronization using {@link createShardOwner}
17
+ *
18
+ * **{@link SharedOwner}**: Created for collaboration with write access, not
19
+ * meant to be shared directly
20
+ *
21
+ * **{@link SharedReadonlyOwner}**: Read-only version for safe data sharing,
22
+ * created from {@link SharedOwner} using {@link createSharedReadonlyOwner}
23
+ *
24
+ * Owners are designed for data synchronization and backup. Authentication
25
+ * systems built on public/private key cryptography use these primitives. This
26
+ * design ensures Evolu Relay knows as little as possible - it only sees
27
+ * Timestamp, OwnerId, and EncryptedDbChange.
3
28
  *
4
29
  * @module
5
30
  */
6
31
 
7
- import { assert } from "../Assert.js";
32
+ import { NonEmptyReadonlyArray } from "../Array.js";
8
33
  import {
9
- createEncryptionKey,
10
34
  CreateMnemonicDep,
11
35
  CreateRandomBytesDep,
12
36
  createSlip21,
@@ -15,61 +39,26 @@ import {
15
39
  MnemonicSeed,
16
40
  mnemonicToMnemonicSeed,
17
41
  } from "../Crypto.js";
18
- import { NanoIdLibDep } from "../NanoId.js";
19
- import { TimeDep } from "../Time.js";
20
42
  import {
21
43
  Base64Url,
22
44
  brand,
23
- DateIso,
24
- DateIsoString,
25
45
  Id,
26
46
  length,
27
47
  Mnemonic,
28
48
  NonNegativeInt,
29
49
  Uint8Array,
30
50
  } from "../Type.js";
31
- import {
32
- createInitialTimestamp,
33
- TimestampString,
34
- timestampToTimestampString,
35
- } from "./Timestamp.js";
36
-
37
- // TODO: Clean API
38
- // - createOwner should be createAppOwner
39
- // - Docs mention WriteKey is optional but it's required in Owner.
40
- // - For Protocol, we need only ownerId, encryptionKey, and writeKey.
41
- // - Not sure whether we need JSDoc for this module, and we don't
42
- // use modules for Evolu internal API yet.
43
- // It's not single responsibility API.
44
51
 
45
52
  /**
46
- * `Owner` is an entity in Evolu that owns data, meaning it is locally stored on
47
- * a device under the user’s control. Data can be personal private, peer-to-peer
48
- * shared, or aggregated from multiple owners.
49
- *
50
- * An owner has a {@link Mnemonic} from which {@link OwnerId} and
51
- * {@link EncryptionKey} are deterministically derived using SLIP-21, and an
52
- * optional {@link WriteKey} that, when present, enables writing to the Evolu
53
- * Relay or peers. The {@link WriteKey} can be rotated.
53
+ * Represents ownership of data in Evolu. Created from a {@link Mnemonic} via
54
+ * SLIP-21 key derivation using {@link createOwner}, providing cryptographic keys
55
+ * for data access and authentication.
54
56
  *
55
- * Variants include {@link AppOwner}, {@link ShardOwner}, {@link SharedOwner}, and
56
- * {@link SharedReadonlyOwner}, each with specific roles and properties detailed
57
- * in their respective definitions.
58
- *
59
- * Public-key cryptography isn’t included here as it belongs to app and varies
60
- * by use case. An Evolu app without collaboration doesn’t need it, while a
61
- * Nostr-like app can leverage Nostr NIPs, or a super-safe app can use
62
- * post-quantum cryptography.
57
+ * - {@link OwnerId}: Globally unique public identifier
58
+ * - {@link EncryptionKey}: Symmetric encryption key for data protection
59
+ * - {@link WriteKey}: Authentication token for write operations (rotatable)
63
60
  */
64
61
  export interface Owner {
65
- readonly mnemonic: Mnemonic;
66
- readonly createdAt: DateIsoString;
67
- readonly id: OwnerId;
68
- readonly encryptionKey: EncryptionKey;
69
- readonly writeKey: WriteKey;
70
- }
71
-
72
- export interface OwnerWithWriteAccess {
73
62
  readonly id: OwnerId;
74
63
  readonly encryptionKey: EncryptionKey;
75
64
  readonly writeKey: WriteKey;
@@ -89,203 +78,140 @@ export type OwnerId = typeof OwnerId.Type;
89
78
  export const writeKeyLength = 16 as NonNegativeInt;
90
79
 
91
80
  /**
92
- * A secure token proving the initiator can write changes. Derived from a
93
- * mnemonic or randomly generated. It's rotatable.
81
+ * A secure token proving that the initiator can write changes. Derived from a
82
+ * mnemonic or randomly generated via {@link createWriteKey}. It is rotatable.
94
83
  */
95
84
  export const WriteKey = brand("WriteKey", length(writeKeyLength)(Uint8Array));
96
85
  export type WriteKey = typeof WriteKey.Type;
97
86
 
98
- /**
99
- * The root owner of an Evolu app, created from a mnemonic safely generated on a
100
- * device when the app is initialized or restored on another device using an
101
- * existing mnemonic. It manages the app's core data, including the storage of
102
- * other owners' mnemonics in an encrypted app table. Its `writeKey` is
103
- * deterministic and rotatable. Never share the AppOwner mnemonic with anyone.
104
- */
105
- export interface AppOwner extends Owner {
106
- readonly type: "AppOwner";
107
- }
87
+ /** Creates a randomly generated {@link WriteKey}. */
88
+ export const createWriteKey = (deps: CreateRandomBytesDep): WriteKey =>
89
+ deps.createRandomBytes(16) as unknown as WriteKey;
108
90
 
109
- /**
110
- * Used to shard data within an app for partial or deferred sync. Created in the
111
- * Evolu `initialData` function or dynamically as needed. Its mnemonic is stored
112
- * in an app table (encrypted by `AppOwner`) and synced between devices. Its
113
- * `writeKey` is deterministic and rotatable, enabling selective syncing of data
114
- * subsets. Not intended for sharing outside the app.
115
- *
116
- * This type omits `id`, `encryptionKey`, and `createdAt` as they are derived by
117
- * Evolu from the `mnemonic`, reducing storage overhead.
118
- */
119
- export interface ShardOwner {
120
- readonly type: "ShardOwner";
121
- readonly mnemonic: Mnemonic;
122
- readonly writeKey: WriteKey;
123
- }
91
+ /** Creates an {@link Owner} from a {@link Mnemonic} using SLIP-21 key derivation. */
92
+ export const createOwner = (mnemonic: Mnemonic): Owner => {
93
+ const seed = mnemonicToMnemonicSeed(mnemonic);
94
+ return createOwnerFromMnemonicSeed(seed);
95
+ };
124
96
 
125
97
  /**
126
- * Used to share data among one or more users, enabling collaboration or
127
- * controlled access. Its `writeKey` is random (not derived from the mnemonic,
128
- * stored alongside it in the app table) and rotatable, ensuring it cannot be
129
- * regenerated by others if shared. Share the `mnemonic` alone for read-only
130
- * access (as `SharedReadonlyOwner`) or share SharedOwner itself for write
131
- * access.
132
- *
133
- * This type omits `id`, `encryptionKey`, and `createdAt` as they are derived by
134
- * Evolu from the `mnemonic`, reducing storage overhead.
98
+ * Creates an {@link Owner} from a {@link MnemonicSeed} using SLIP-21 key
99
+ * derivation.
135
100
  */
136
- export interface SharedOwner {
137
- readonly type: "SharedOwner";
138
- readonly mnemonic: Mnemonic;
139
- readonly writeKey: WriteKey;
140
- }
101
+ export const createOwnerFromMnemonicSeed = (seed: MnemonicSeed): Owner => ({
102
+ id: createSlip21Id(seed, ["Evolu", "Owner Id"]) as OwnerId,
103
+
104
+ encryptionKey: createSlip21(seed, [
105
+ "Evolu",
106
+ "Encryption Key",
107
+ ]) as EncryptionKey,
108
+
109
+ writeKey: createSlip21(seed, ["Evolu", "Write Key"]).slice(0, 16) as WriteKey,
110
+ });
141
111
 
142
112
  /**
143
- * Used for sharing data that can only be read, such as with followers or peers
144
- * in a read-only sync scenario. It lacks a `writeKey`, containing only the
145
- * `mnemonic` from which `id` and `encryptionKey` are derived by Evolu.
146
- * Typically derived from a `SharedOwner` by sharing its `mnemonic` without the
147
- * `writeKey`.
113
+ * The owner representing app data. Can be created from a {@link Mnemonic} or
114
+ * from external keys when the mnemonic should not be shared with the Evolu
115
+ * app.
148
116
  */
149
- export interface SharedReadonlyOwner {
150
- readonly type: "SharedReadonlyOwner";
151
- readonly mnemonic: Mnemonic;
117
+ export interface AppOwner extends Owner {
118
+ readonly type: "AppOwner";
119
+
120
+ /**
121
+ * The mnemonic that was used to derive the AppOwner keys. Optional when the
122
+ * AppOwner is created from external keys to avoid sharing the mnemonic with
123
+ * the Evolu app.
124
+ */
125
+ readonly mnemonic?: Mnemonic | null;
152
126
  }
153
127
 
128
+ export const createAppOwner = (mnemonic: Mnemonic): AppOwner => ({
129
+ type: "AppOwner",
130
+ mnemonic,
131
+ ...createOwner(mnemonic),
132
+ });
133
+
154
134
  /**
155
- * Creates an {@link AppOwner}, optionally from an existing mnemonic to restore
156
- * it on another device; otherwise, generates a new mnemonic.
135
+ * Owner for sharding app data. Allows partitioning of database changes for
136
+ * selective synchronization.
157
137
  */
158
- export const createAppOwner =
159
- (deps: TimeDep & CreateRandomBytesDep & CreateMnemonicDep) =>
160
- (mnemonic = deps.createMnemonic()): AppOwner => {
161
- const owner = createOwner(deps)(mnemonic);
162
- return { type: "AppOwner", ...owner };
163
- };
138
+ export interface ShardOwner extends Owner {
139
+ readonly type: "ShardOwner";
140
+ }
164
141
 
165
142
  /**
166
- * Creates a {@link ShardOwner} for sharding app data with a freshly generated
167
- * mnemonic. Unlike {@link createAppOwner}, it doesn’t accept an existing
168
- * mnemonic because ShardOwner mnemonics are always generated and restored
169
- * automatically via database sync.
143
+ * Creates a {@link ShardOwner} derived from an {@link AppOwner} using the
144
+ * specified path.
145
+ *
146
+ * ### Example
147
+ *
148
+ * ```ts
149
+ * const contactsShard = createShardOwner(appOwner, ["contacts"]);
150
+ * const projectShard = createShardOwner(appOwner, [
151
+ * "projects",
152
+ * "project-1",
153
+ * ]);
154
+ * ```
170
155
  */
171
156
  export const createShardOwner = (
172
- deps: TimeDep & CreateRandomBytesDep & CreateMnemonicDep,
157
+ appOwner: AppOwner,
158
+ path: NonEmptyReadonlyArray<string>,
173
159
  ): ShardOwner => {
174
- const owner = createOwner(deps)();
160
+ /**
161
+ * The shardSeed is never shared or persisted, only used for SLIP-21
162
+ * derivation to create shard-specific keys.
163
+ */
164
+ const shardSeed = createSlip21(
165
+ appOwner.encryptionKey as unknown as MnemonicSeed,
166
+ path,
167
+ ) as MnemonicSeed;
168
+
175
169
  return {
176
170
  type: "ShardOwner",
177
- mnemonic: owner.mnemonic,
178
- writeKey: owner.writeKey,
171
+ ...createOwnerFromMnemonicSeed(shardSeed),
179
172
  };
180
173
  };
181
174
 
182
175
  /**
183
- * Creates a fresh {@link SharedOwner} for sharing data with write access. Takes
184
- * no arguments as both `mnemonic` and rotatable `writeKey` are newly generated;
185
- * when shared, recipients use the provided `mnemonic` and `writeKey` directly
186
- * as a {@link SharedOwner} without needing to recreate it.
176
+ * Owner for collaborative data with write access. Created by a user for their
177
+ * own use, not meant to be shared directly. To share data, use
178
+ * {@link createSharedReadonlyOwner} to create a {@link SharedReadonlyOwner} for
179
+ * read-only access.
187
180
  */
188
- export const createSharedOwner = (
189
- deps: CreateRandomBytesDep & CreateMnemonicDep,
190
- ): SharedOwner => {
181
+ export interface SharedOwner extends Owner {
182
+ readonly type: "SharedOwner";
183
+ readonly mnemonic: Mnemonic;
184
+ }
185
+
186
+ /** Creates a {@link SharedOwner} with a freshly generated {@link Mnemonic}. */
187
+ export const createSharedOwner = (deps: CreateMnemonicDep): SharedOwner => {
191
188
  const mnemonic = deps.createMnemonic();
192
- const writeKey = createWriteKey(deps)(); // Random, no seed
193
189
  return {
194
190
  type: "SharedOwner",
195
191
  mnemonic,
196
- writeKey,
192
+ ...createOwner(mnemonic),
197
193
  };
198
194
  };
199
195
 
200
196
  /**
201
- * Creates a {@link SharedReadonlyOwner} from a {@link SharedOwner} for read-only
202
- * data sharing. Extracts the `mnemonic` from the provided {@link SharedOwner},
203
- * omitting its `writeKey` to ensure read-only access.
197
+ * Read-only version of a {@link SharedOwner} for data sharing. Contains only the
198
+ * {@link OwnerId} and {@link EncryptionKey} needed for others to read the shared
199
+ * data without write access.
204
200
  */
201
+ export interface SharedReadonlyOwner {
202
+ readonly type: "SharedReadonlyOwner";
203
+ readonly id: OwnerId;
204
+ readonly encryptionKey: EncryptionKey;
205
+ }
206
+
207
+ /** Creates a {@link SharedReadonlyOwner} from a {@link SharedOwner}. */
205
208
  export const createSharedReadonlyOwner = (
206
209
  sharedOwner: SharedOwner,
207
- ): SharedReadonlyOwner => {
208
- return {
209
- type: "SharedReadonlyOwner",
210
- mnemonic: sharedOwner.mnemonic,
211
- };
212
- };
213
-
214
- /** Creates an {@link Owner} with optional `mnemonic` and `writeKey`. */
215
- export const createOwner =
216
- (deps: TimeDep & CreateRandomBytesDep & CreateMnemonicDep) =>
217
- (mnemonic = deps.createMnemonic(), writeKey?: WriteKey): Owner => {
218
- const seed = mnemonicToMnemonicSeed(mnemonic);
219
-
220
- const id = createSlip21Id(seed, ["Evolu", "Owner Id"]) as OwnerId;
221
- const encryptionKey = createEncryptionKey(seed);
222
-
223
- const createdAt = DateIso.fromParent(new Date(deps.time.now()));
224
- assert(createdAt.ok, "Invalid DateIso: bad system clock");
225
-
226
- return {
227
- mnemonic,
228
- createdAt: createdAt.value,
229
- id,
230
- encryptionKey,
231
- writeKey: writeKey ?? createWriteKey(deps)(seed),
232
- };
233
- };
234
-
235
- export const createWriteKey =
236
- (deps: CreateRandomBytesDep) =>
237
- (seed?: MnemonicSeed): WriteKey => {
238
- const key = seed
239
- ? createSlip21(seed, ["Evolu", "Write Key"]).slice(0, 16)
240
- : deps.createRandomBytes(16);
241
-
242
- const writeKey = WriteKey.from(key);
243
- assert(writeKey.ok, "Ensure valid WriteKey");
244
-
245
- return writeKey.value;
246
- };
247
-
248
- /**
249
- * An `OwnerRow` represents a row in the `evolu_owner` table, based on an
250
- * {@link Owner} with an added `timestamp` ({@link TimestampString}) for CRDT
251
- * sync. It supports all {@link Owner} variants with an optional `writeKey`; use
252
- * {@link createOwnerRow} to align it with a specific {@link Owner}.
253
- */
254
- export type OwnerRow = Omit<Owner, "writeKey"> & {
255
- readonly writeKey: WriteKey | null;
256
- readonly timestamp: TimestampString;
257
- };
258
-
259
- /**
260
- * Creates an {@link OwnerRow} from any {@link Owner} variant for the
261
- * `evolu_owner` table, adding a `timestamp` ({@link TimestampString}) for CRDT
262
- * sync.
263
- */
264
- export const createOwnerRow =
265
- (deps: TimeDep & CreateRandomBytesDep & CreateMnemonicDep & NanoIdLibDep) =>
266
- (
267
- owner: AppOwner | ShardOwner | SharedOwner | SharedReadonlyOwner,
268
- ): OwnerRow => {
269
- const timestamp = timestampToTimestampString(createInitialTimestamp(deps));
270
- switch (owner.type) {
271
- case "AppOwner": {
272
- const { type, ...rest } = owner;
273
- return { ...rest, timestamp };
274
- }
275
- case "ShardOwner":
276
- case "SharedOwner":
277
- return {
278
- ...createOwner(deps)(owner.mnemonic, owner.writeKey),
279
- timestamp,
280
- };
281
- case "SharedReadonlyOwner":
282
- return {
283
- ...createOwner(deps)(owner.mnemonic),
284
- writeKey: null,
285
- timestamp,
286
- };
287
- }
288
- };
210
+ ): SharedReadonlyOwner => ({
211
+ type: "SharedReadonlyOwner",
212
+ id: sharedOwner.id,
213
+ encryptionKey: sharedOwner.encryptionKey,
214
+ });
289
215
 
290
216
  /**
291
217
  * Rotates the {@link WriteKey} for an {@link AppOwner}, {@link ShardOwner}, or
@@ -1,3 +1,4 @@
1
+ /* eslint-disable jsdoc/no-undefined-types */
1
2
  /**
2
3
  * Evolu Protocol
3
4
  *
@@ -183,13 +184,7 @@ import {
183
184
  record,
184
185
  } from "../Type.js";
185
186
  import { Brand, Predicate } from "../Types.js";
186
- import {
187
- Owner,
188
- OwnerId,
189
- OwnerWithWriteAccess,
190
- WriteKey,
191
- writeKeyLength,
192
- } from "./Owner.js";
187
+ import { Owner, OwnerId, WriteKey, writeKeyLength } from "./Owner.js";
193
188
  import {
194
189
  BinaryTimestamp,
195
190
  binaryTimestampLength,
@@ -473,7 +468,7 @@ export interface ProtocolTimestampMismatchError {
473
468
  export const createProtocolMessageFromCrdtMessages =
474
469
  (deps: SymmetricCryptoDep & CreateRandomBytesDep) =>
475
470
  (
476
- owner: OwnerWithWriteAccess,
471
+ owner: Owner,
477
472
  messages: NonEmptyReadonlyArray<CrdtMessage>,
478
473
  maxSize?: PositiveInt,
479
474
  ): ProtocolMessage => {
@@ -5,12 +5,7 @@
5
5
  */
6
6
 
7
7
  export { createEvolu } from "./Evolu.js";
8
- export type {
9
- Evolu,
10
- EvoluConfigWithInitialData,
11
- EvoluDeps,
12
- EvoluError,
13
- } from "./Evolu.js";
8
+ export type { Evolu, EvoluDeps, EvoluError } from "./Evolu.js";
14
9
  export * from "./Owner.js";
15
10
  export { binaryIdToId, idToBinaryId } from "./Protocol.js";
16
11
  export type { BinaryId } from "./Protocol.js";
@@ -30,11 +30,10 @@ import {
30
30
  import { Simplify } from "../Types.js";
31
31
  import { DbSchema } from "./Db.js";
32
32
  import { createIndexes, DbIndexesBuilder } from "./Kysely.js";
33
- import { AppOwner, ShardOwner, SharedOwner } from "./Owner.js";
34
33
  import {
35
34
  BinaryId,
36
- maxProtocolMessageRangesSize,
37
35
  CrdtMessage,
36
+ maxProtocolMessageRangesSize,
38
37
  } from "./Protocol.js";
39
38
  import { Query, Row } from "./Query.js";
40
39
  import { BinaryTimestamp } from "./Timestamp.js";
@@ -252,13 +251,6 @@ export interface MutationOptions {
252
251
  * `onlyValidate: true`.
253
252
  */
254
253
  readonly onlyValidate?: boolean;
255
-
256
- /**
257
- * The owner to use for this mutation. Can be a {@link ShardOwner} for sharding
258
- * app data or a {@link SharedOwner} for collaborative write access. If
259
- * omitted, defaults to the app's {@link AppOwner}.
260
- */
261
- readonly owner?: ShardOwner | SharedOwner;
262
254
  }
263
255
 
264
256
  /**
package/src/Result.ts CHANGED
@@ -1,3 +1,4 @@
1
+ /* eslint-disable jsdoc/no-undefined-types */
1
2
  /**
2
3
  * 🛡️ Type-safe errors
3
4
  *
package/src/Type.ts CHANGED
@@ -1,3 +1,4 @@
1
+ /* eslint-disable jsdoc/no-undefined-types */
1
2
  /**
2
3
  * 🧩 Validation, Parsing, and Transformation
3
4
  *