Skip to content

Commit 6eca947

Browse files
committed
Replace initialData with onInit callback
1 parent 9bb9dd9 commit 6eca947

14 files changed

Lines changed: 849 additions & 210 deletions

File tree

.changeset/major-insects-cough.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
"@evolu/common": patch
3+
---
4+
5+
Replace initialData with onInit callback
6+
7+
- Remove `initialData` function from Config interface
8+
- Add `onInit` callback with `isFirst` parameter for one-time initialization
9+
- Simplify database initialization by removing pre-init data handling
10+
- Provide better control over initialization lifecycle

apps/web/src/components/NextJsExample.tsx

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -109,17 +109,19 @@ const evolu = createEvolu(evoluReactWebDeps)(Schema, {
109109
syncUrl: "http://localhost:4000",
110110
}),
111111

112-
initialData: (evolu) => {
113-
const todoCategoryId = getOrThrow(
114-
evolu.insert("todoCategory", {
115-
name: "Not Urgent",
116-
}),
117-
);
118-
119-
evolu.insert("todo", {
120-
title: "Try React Suspense",
121-
categoryId: todoCategoryId.id,
122-
});
112+
onInit: ({ isFirst }) => {
113+
if (isFirst) {
114+
const todoCategoryId = getOrThrow(
115+
evolu.insert("todoCategory", {
116+
name: "Not Urgent",
117+
}),
118+
);
119+
120+
evolu.insert("todo", {
121+
title: "Try React Suspense",
122+
categoryId: todoCategoryId.id,
123+
});
124+
}
123125
},
124126

125127
// Indexes are not required for development but are recommended for production.

examples/react-electron/src/EvoluDemo.tsx

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import {
2-
assert,
32
createEvolu,
43
createFormatTypeError,
54
FiniteNumber,
@@ -21,8 +20,8 @@ import {
2120
import {
2221
createUseEvolu,
2322
EvoluProvider,
24-
useEvoluError,
2523
useAppOwner,
24+
useEvoluError,
2625
useQuery,
2726
} from "@evolu/react";
2827
import { evoluReactWebDeps } from "@evolu/react-web";
@@ -77,18 +76,19 @@ const evolu = createEvolu(evoluReactWebDeps)(Schema, {
7776
syncUrl: "http://localhost:4000",
7877
}),
7978

80-
initialData: (evolu) => {
81-
const todoCategory = evolu.insert("todoCategory", {
82-
name: "Not Urgent",
83-
});
84-
85-
// This is a developer error, which should be fixed immediately.
86-
assert(todoCategory.ok, "invalid initial data");
87-
88-
evolu.insert("todo", {
89-
title: "Try React Suspense",
90-
categoryId: todoCategory.value.id,
91-
});
79+
onInit: ({ isFirst }) => {
80+
if (isFirst) {
81+
const todoCategoryId = getOrThrow(
82+
evolu.insert("todoCategory", {
83+
name: "Not Urgent",
84+
}),
85+
);
86+
87+
evolu.insert("todo", {
88+
title: "Try React Suspense",
89+
categoryId: todoCategoryId.id,
90+
});
91+
}
9292
},
9393

9494
// Indexes are not necessary for development but are recommended for production.

examples/react-expo/app/index.tsx

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import {
2-
assert,
32
createEvolu,
43
getOrThrow,
54
id,
@@ -62,18 +61,19 @@ const evolu = createEvolu(evoluReactNativeDeps)(Schema, {
6261
syncUrl: "http://localhost:4000",
6362
}),
6463

65-
initialData: (evolu) => {
66-
const todoCategory = evolu.insert("todoCategory", {
67-
name: "Not Urgent",
68-
});
69-
70-
// This is a developer error, which should be fixed immediately.
71-
assert(todoCategory.ok, "invalid initial data");
72-
73-
evolu.insert("todo", {
74-
title: "Try React Suspense",
75-
categoryId: todoCategory.value.id,
76-
});
64+
onInit: ({ isFirst }) => {
65+
if (isFirst) {
66+
const todoCategoryId = getOrThrow(
67+
evolu.insert("todoCategory", {
68+
name: "Not Urgent",
69+
}),
70+
);
71+
72+
evolu.insert("todo", {
73+
title: "Try React Suspense",
74+
categoryId: todoCategoryId.id,
75+
});
76+
}
7777
},
7878

7979
// Indexes are not required for development but are recommended for production.

examples/react-nextjs/components/NextJsExample.tsx

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"use client";
22

33
import {
4-
assert,
54
binaryTimestampToTimestamp,
65
createEvolu,
76
createFormatTypeError,
@@ -108,18 +107,19 @@ const evolu = createEvolu(evoluReactWebDeps)(Schema, {
108107
syncUrl: "http://localhost:4000",
109108
}),
110109

111-
initialData: (evolu) => {
112-
const todoCategory = evolu.insert("todoCategory", {
113-
name: "Not Urgent",
114-
});
115-
116-
// This is a developer error, which should be fixed immediately.
117-
assert(todoCategory.ok, "invalid initial data");
118-
119-
evolu.insert("todo", {
120-
title: "Try React Suspense",
121-
categoryId: todoCategory.value.id,
122-
});
110+
onInit: ({ isFirst }) => {
111+
if (isFirst) {
112+
const todoCategoryId = getOrThrow(
113+
evolu.insert("todoCategory", {
114+
name: "Not Urgent",
115+
}),
116+
);
117+
118+
evolu.insert("todo", {
119+
title: "Try React Suspense",
120+
categoryId: todoCategoryId.id,
121+
});
122+
}
123123
},
124124

125125
// Indexes are not required for development but are recommended for production.

examples/react-vite-pwa/src/components/EvoluDemo.tsx

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"use client";
22

33
import {
4-
assert,
54
binaryTimestampToTimestamp,
65
createEvolu,
76
createFormatTypeError,
@@ -25,8 +24,8 @@ import {
2524
import {
2625
createUseEvolu,
2726
EvoluProvider,
28-
useEvoluError,
2927
useAppOwner,
28+
useEvoluError,
3029
useQuery,
3130
} from "@evolu/react";
3231
import { evoluReactWebDeps } from "@evolu/react-web";
@@ -110,18 +109,19 @@ const evolu = createEvolu(evoluReactWebDeps)(Schema, {
110109
syncUrl: "http://localhost:4000",
111110
}),
112111

113-
initialData: (evolu) => {
114-
const todoCategory = evolu.insert("todoCategory", {
115-
name: "Not Urgent",
116-
});
117-
118-
// This is a developer error, which should be fixed immediately.
119-
assert(todoCategory.ok, "invalid initial data");
120-
121-
evolu.insert("todo", {
122-
title: "Try React Suspense",
123-
categoryId: todoCategory.value.id,
124-
});
112+
onInit: ({ isFirst }) => {
113+
if (isFirst) {
114+
const todoCategoryId = getOrThrow(
115+
evolu.insert("todoCategory", {
116+
name: "Not Urgent",
117+
}),
118+
);
119+
120+
evolu.insert("todo", {
121+
title: "Try React Suspense",
122+
categoryId: todoCategoryId.id,
123+
});
124+
}
125125
},
126126

127127
// Indexes are not required for development but are recommended for production.

examples/svelte-vite-pwa/src/App.svelte

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
NonEmptyString1000,
66
SimpleName,
77
SqliteBoolean,
8-
assert,
98
createEvolu,
109
createFormatTypeError,
1110
getOrThrow,
@@ -69,18 +68,20 @@
6968
syncUrl: "http://localhost:4000",
7069
}),
7170
72-
initialData: (_evolu) => {
73-
const todoCategory = _evolu.insert("todoCategory", {
74-
name: getOrThrow(NonEmptyString50.from("Not Urgent")),
75-
});
76-
77-
assert(todoCategory.ok, "invalid initial data");
78-
79-
_evolu.insert("todo", {
80-
title: getOrThrow(NonEmptyString1000.from("Try svelte $derived")),
81-
categoryId: todoCategory.value.id,
82-
priority: "low",
83-
});
71+
onInit: ({ isFirst }) => {
72+
if (isFirst) {
73+
const todoCategoryId = getOrThrow(
74+
evolu.insert("todoCategory", {
75+
name: "Not Urgent",
76+
}),
77+
);
78+
79+
evolu.insert("todo", {
80+
title: "Try React Suspense",
81+
categoryId: todoCategoryId.id,
82+
priority: "low",
83+
});
84+
}
8485
},
8586
8687
// Indexes are not necessary for development but are recommended for production.

packages/common/src/Evolu/Db.ts

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
import {
2-
isNonEmptyArray,
3-
isNonEmptyReadonlyArray,
4-
NonEmptyReadonlyArray,
5-
} from "../Array.js";
1+
import { isNonEmptyArray, NonEmptyReadonlyArray } from "../Array.js";
62
import { assert, assertNonEmptyReadonlyArray } from "../Assert.js";
73
import { CallbackId } from "../Callbacks.js";
84
import { ConsoleDep } from "../Console.js";
@@ -121,7 +117,6 @@ export type DbWorkerInput =
121117
readonly type: "init";
122118
readonly config: Config;
123119
readonly dbSchema: DbSchema;
124-
readonly initialData: ReadonlyArray<DbChange>;
125120
}
126121
| {
127122
readonly type: "mutate";
@@ -157,6 +152,7 @@ export type DbWorkerOutput =
157152
| {
158153
readonly type: "onInit";
159154
readonly appOwner: AppOwner;
155+
readonly isFirst: boolean;
160156
}
161157
| {
162158
readonly type: "onError";
@@ -289,11 +285,11 @@ export const createDbWorkerForPlatform = (
289285
let appOwner: AppOwner;
290286
let clock: Clock;
291287

292-
const versionTableExists = currentDbSchema.value.tables.some(
288+
const dbIsInitialized = currentDbSchema.value.tables.some(
293289
(table) => table.name === "evolu_version",
294290
);
295291

296-
if (versionTableExists) {
292+
if (dbIsInitialized) {
297293
const versionResult = sqlite.exec<{
298294
protocolVersion: number;
299295
}>(sql`select protocolVersion from evolu_version limit 1;`);
@@ -383,15 +379,11 @@ export const createDbWorkerForPlatform = (
383379
storage: storage.value,
384380
};
385381

386-
if (
387-
!versionTableExists &&
388-
isNonEmptyReadonlyArray(initMessage.initialData)
389-
) {
390-
const result = applyChanges(depsWithoutSync)(initMessage.initialData);
391-
if (!result.ok) return result;
392-
}
393-
394-
postMessage({ type: "onInit", appOwner });
382+
postMessage({
383+
type: "onInit",
384+
appOwner,
385+
isFirst: !dbIsInitialized,
386+
});
395387

396388
const sync = platformDeps.createSync(platformDeps)({
397389
...initMessage.config,

0 commit comments

Comments
 (0)