@evolu/common 5.4.8 → 6.0.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.
- package/README.md +30 -34
- package/dist/src/Array.d.ts +17 -0
- package/dist/src/Array.d.ts.map +1 -0
- package/dist/src/Array.js +12 -0
- package/dist/src/Assert.d.ts +68 -0
- package/dist/src/Assert.d.ts.map +1 -0
- package/dist/src/Assert.js +77 -0
- package/dist/src/BigInt.d.ts +20 -0
- package/dist/src/BigInt.d.ts.map +1 -0
- package/dist/src/BigInt.js +18 -0
- package/dist/src/Buffer.d.ts +92 -0
- package/dist/src/Buffer.d.ts.map +1 -0
- package/dist/src/Buffer.js +62 -0
- package/dist/src/Callbacks.d.ts +20 -0
- package/dist/src/Callbacks.d.ts.map +1 -0
- package/dist/src/Callbacks.js +18 -0
- package/dist/src/Console.d.ts +78 -0
- package/dist/src/Console.d.ts.map +1 -0
- package/dist/src/Console.js +103 -0
- package/dist/src/Crypto.d.ts +72 -39
- package/dist/src/Crypto.d.ts.map +1 -1
- package/dist/src/Crypto.js +89 -54
- package/dist/src/Eq.d.ts +97 -0
- package/dist/src/Eq.d.ts.map +1 -0
- package/dist/src/Eq.js +167 -0
- package/dist/src/Error.d.ts +14 -10
- package/dist/src/Error.d.ts.map +1 -1
- package/dist/src/Error.js +43 -11
- package/dist/src/Evolu/Config.d.ts +69 -0
- package/dist/src/Evolu/Config.d.ts.map +1 -0
- package/dist/src/Evolu/Config.js +9 -0
- package/dist/src/Evolu/Db.d.ts +126 -0
- package/dist/src/Evolu/Db.d.ts.map +1 -0
- package/dist/src/Evolu/Db.js +774 -0
- package/dist/src/Evolu/Diff.d.ts +43 -0
- package/dist/src/Evolu/Diff.d.ts.map +1 -0
- package/dist/src/Evolu/Diff.js +95 -0
- package/dist/src/Evolu/Evolu.d.ts +334 -0
- package/dist/src/Evolu/Evolu.d.ts.map +1 -0
- package/dist/src/Evolu/Evolu.js +434 -0
- package/dist/src/Evolu/Internal.d.ts +26 -0
- package/dist/src/Evolu/Internal.d.ts.map +1 -0
- package/dist/src/Evolu/Internal.js +25 -0
- package/dist/src/Evolu/Kysely.d.ts +6 -0
- package/dist/src/Evolu/Kysely.d.ts.map +1 -0
- package/dist/src/Evolu/Kysely.js +21 -0
- package/dist/src/Evolu/Owner.d.ts +155 -0
- package/dist/src/Evolu/Owner.d.ts.map +1 -0
- package/dist/src/Evolu/Owner.js +126 -0
- package/dist/src/Evolu/Platform.d.ts +23 -0
- package/dist/src/Evolu/Platform.d.ts.map +1 -0
- package/dist/src/Evolu/Platform.js +1 -0
- package/dist/src/Evolu/Protocol.d.ts +401 -0
- package/dist/src/Evolu/Protocol.d.ts.map +1 -0
- package/dist/src/Evolu/Protocol.js +1151 -0
- package/dist/src/Evolu/Public.d.ts +18 -0
- package/dist/src/Evolu/Public.d.ts.map +1 -0
- package/dist/src/Evolu/Public.js +11 -0
- package/dist/src/Evolu/PublicKysely.d.ts +148 -0
- package/dist/src/Evolu/PublicKysely.d.ts.map +1 -0
- package/dist/src/Evolu/PublicKysely.js +185 -0
- package/dist/src/Evolu/Query.d.ts +63 -0
- package/dist/src/Evolu/Query.d.ts.map +1 -0
- package/dist/src/Evolu/Query.js +61 -0
- package/dist/src/Evolu/Relay.d.ts +13 -0
- package/dist/src/Evolu/Relay.d.ts.map +1 -0
- package/dist/src/Evolu/Relay.js +109 -0
- package/dist/src/Evolu/Schema.d.ts +201 -0
- package/dist/src/Evolu/Schema.d.ts.map +1 -0
- package/dist/src/Evolu/Schema.js +150 -0
- package/dist/src/Evolu/Storage.d.ts +49 -0
- package/dist/src/Evolu/Storage.d.ts.map +1 -0
- package/dist/src/Evolu/Storage.js +1111 -0
- package/dist/src/Evolu/Sync.d.ts +59 -0
- package/dist/src/Evolu/Sync.d.ts.map +1 -0
- package/dist/src/Evolu/Sync.js +29 -0
- package/dist/src/Evolu/Timestamp.d.ts +106 -0
- package/dist/src/Evolu/Timestamp.d.ts.map +1 -0
- package/dist/src/Evolu/Timestamp.js +179 -0
- package/dist/src/Function.d.ts +54 -0
- package/dist/src/Function.d.ts.map +1 -0
- package/dist/src/Function.js +38 -0
- package/dist/src/ManyToManyMap.d.ts +26 -0
- package/dist/src/ManyToManyMap.d.ts.map +1 -0
- package/dist/src/ManyToManyMap.js +92 -0
- package/dist/src/NanoId.d.ts +27 -0
- package/dist/src/NanoId.d.ts.map +1 -0
- package/dist/src/NanoId.js +6 -0
- package/dist/src/Number.d.ts +42 -0
- package/dist/src/Number.d.ts.map +1 -0
- package/dist/src/Number.js +55 -0
- package/dist/src/Object.d.ts +35 -0
- package/dist/src/Object.d.ts.map +1 -0
- package/dist/src/Object.js +36 -0
- package/dist/src/Order.d.ts +90 -0
- package/dist/src/Order.d.ts.map +1 -0
- package/dist/src/Order.js +85 -0
- package/dist/src/Promise.d.ts +180 -0
- package/dist/src/Promise.d.ts.map +1 -0
- package/dist/src/Promise.js +176 -0
- package/dist/src/Random.d.ts +52 -0
- package/dist/src/Random.d.ts.map +1 -0
- package/dist/src/Random.js +29 -0
- package/dist/src/Ref.d.ts +40 -0
- package/dist/src/Ref.d.ts.map +1 -0
- package/dist/src/Ref.js +13 -0
- package/dist/src/Result.d.ts +421 -0
- package/dist/src/Result.d.ts.map +1 -0
- package/dist/src/Result.js +357 -0
- package/dist/src/Skiplist.d.ts +23 -0
- package/dist/src/Skiplist.d.ts.map +1 -0
- package/dist/src/Skiplist.js +58 -0
- package/dist/src/Sqlite.d.ts +116 -52
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +183 -67
- package/dist/src/Store.d.ts +45 -8
- package/dist/src/Store.d.ts.map +1 -1
- package/dist/src/Store.js +33 -17
- package/dist/src/String.d.ts +2 -0
- package/dist/src/String.d.ts.map +1 -0
- package/dist/src/String.js +14 -0
- package/dist/src/Time.d.ts +20 -0
- package/dist/src/Time.d.ts.map +1 -0
- package/dist/src/Time.js +25 -0
- package/dist/src/Type.d.ts +1937 -0
- package/dist/src/Type.d.ts.map +1 -0
- package/dist/src/Type.js +2002 -0
- package/dist/src/Types.d.ts +188 -0
- package/dist/src/Types.d.ts.map +1 -0
- package/dist/src/Types.js +6 -0
- package/dist/src/WebSocket.d.ts +112 -0
- package/dist/src/WebSocket.d.ts.map +1 -0
- package/dist/src/WebSocket.js +139 -0
- package/dist/src/Worker.d.ts +44 -0
- package/dist/src/Worker.d.ts.map +1 -0
- package/dist/src/Worker.js +66 -0
- package/dist/src/index.d.ts +24 -11
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +24 -11
- package/package.json +29 -38
- package/src/Array.ts +39 -0
- package/src/Assert.ts +116 -0
- package/src/BigInt.ts +29 -0
- package/src/Buffer.ts +175 -0
- package/src/Callbacks.ts +43 -0
- package/src/Console.ts +159 -0
- package/src/Crypto.ts +169 -115
- package/src/Eq.ts +204 -0
- package/src/Error.ts +57 -20
- package/src/Evolu/Config.ts +83 -0
- package/src/Evolu/Db.ts +1275 -0
- package/src/Evolu/Diff.ts +142 -0
- package/src/Evolu/Evolu.ts +947 -0
- package/src/Evolu/Internal.ts +26 -0
- package/src/Evolu/Kysely.ts +38 -0
- package/src/Evolu/Owner.ts +296 -0
- package/src/Evolu/Platform.ts +27 -0
- package/src/Evolu/Protocol.ts +1857 -0
- package/src/Evolu/Public.ts +43 -0
- package/src/Evolu/PublicKysely.ts +240 -0
- package/src/Evolu/Query.ts +167 -0
- package/src/Evolu/Relay.ts +142 -0
- package/src/Evolu/Schema.ts +417 -0
- package/src/Evolu/Storage.ts +1281 -0
- package/src/Evolu/Sync.ts +105 -0
- package/src/Evolu/Timestamp.ts +311 -0
- package/src/Function.ts +58 -0
- package/src/ManyToManyMap.ts +140 -0
- package/src/NanoId.ts +39 -0
- package/src/Number.ts +90 -0
- package/src/Object.ts +64 -0
- package/src/Order.ts +113 -0
- package/src/Promise.ts +295 -0
- package/src/Random.ts +68 -0
- package/src/Ref.ts +63 -0
- package/src/Result.ts +453 -0
- package/src/Skiplist.ts +102 -0
- package/src/Sqlite.ts +366 -153
- package/src/Store.ts +79 -36
- package/src/String.ts +10 -0
- package/src/Time.ts +36 -0
- package/src/Type.ts +3978 -0
- package/src/Types.ts +209 -0
- package/src/WebSocket.ts +273 -0
- package/src/Worker.ts +129 -0
- package/src/index.ts +24 -11
- package/dist/src/Config.d.ts +0 -56
- package/dist/src/Config.d.ts.map +0 -1
- package/dist/src/Config.js +0 -39
- package/dist/src/Crdt.d.ts +0 -89
- package/dist/src/Crdt.d.ts.map +0 -1
- package/dist/src/Crdt.js +0 -181
- package/dist/src/Db.d.ts +0 -107
- package/dist/src/Db.d.ts.map +0 -1
- package/dist/src/Db.js +0 -443
- package/dist/src/Diff.d.ts +0 -27
- package/dist/src/Diff.d.ts.map +0 -1
- package/dist/src/Diff.js +0 -84
- package/dist/src/Evolu.d.ts +0 -426
- package/dist/src/Evolu.d.ts.map +0 -1
- package/dist/src/Evolu.js +0 -333
- package/dist/src/Model.d.ts +0 -141
- package/dist/src/Model.d.ts.map +0 -1
- package/dist/src/Model.js +0 -125
- package/dist/src/Murmurhash.d.ts +0 -2
- package/dist/src/Murmurhash.d.ts.map +0 -1
- package/dist/src/Murmurhash.js +0 -60
- package/dist/src/Owner.d.ts +0 -33
- package/dist/src/Owner.d.ts.map +0 -1
- package/dist/src/Owner.js +0 -26
- package/dist/src/Platform.d.ts +0 -37
- package/dist/src/Platform.d.ts.map +0 -1
- package/dist/src/Platform.js +0 -11
- package/dist/src/Protobuf.d.ts +0 -81
- package/dist/src/Protobuf.d.ts.map +0 -1
- package/dist/src/Protobuf.js +0 -92
- package/dist/src/Public.d.ts +0 -13
- package/dist/src/Public.d.ts.map +0 -1
- package/dist/src/Public.js +0 -6
- package/dist/src/Socket.d.ts +0 -8
- package/dist/src/Socket.d.ts.map +0 -1
- package/dist/src/Socket.js +0 -51
- package/dist/src/Sql.d.ts +0 -12
- package/dist/src/Sql.d.ts.map +0 -1
- package/dist/src/Sql.js +0 -30
- package/dist/src/Sync.d.ts +0 -70
- package/dist/src/Sync.d.ts.map +0 -1
- package/dist/src/Sync.js +0 -127
- package/src/Config.ts +0 -119
- package/src/Crdt.ts +0 -361
- package/src/Db.ts +0 -955
- package/src/Diff.ts +0 -114
- package/src/Evolu.ts +0 -1016
- package/src/Model.ts +0 -233
- package/src/Murmurhash.ts +0 -70
- package/src/Owner.ts +0 -69
- package/src/Platform.ts +0 -47
- package/src/Protobuf.ts +0 -155
- package/src/Public.ts +0 -12
- package/src/Socket.ts +0 -83
- package/src/Sql.ts +0 -41
- package/src/Sync.ts +0 -315
package/dist/src/Evolu.js
DELETED
|
@@ -1,333 +0,0 @@
|
|
|
1
|
-
import * as AST from "@effect/schema/AST";
|
|
2
|
-
import { make } from "@effect/schema/Schema";
|
|
3
|
-
import * as Arr from "effect/Array";
|
|
4
|
-
import * as Context from "effect/Context";
|
|
5
|
-
import * as Effect from "effect/Effect";
|
|
6
|
-
import { constVoid, flow, pipe } from "effect/Function";
|
|
7
|
-
import * as Layer from "effect/Layer";
|
|
8
|
-
import * as Number from "effect/Number";
|
|
9
|
-
import * as Option from "effect/Option";
|
|
10
|
-
import * as Predicate from "effect/Predicate";
|
|
11
|
-
import * as Record from "effect/Record";
|
|
12
|
-
import * as Kysely from "kysely";
|
|
13
|
-
import { Config, createRuntime, defaultConfig } from "./Config.js";
|
|
14
|
-
import { NanoIdGenerator } from "./Crypto.js";
|
|
15
|
-
import { createSocket } from "./Socket.js";
|
|
16
|
-
import { DbFactory, deserializeQuery, emptyRows, queryResultFromRows, serializeQuery, } from "./Db.js";
|
|
17
|
-
import { applyPatches } from "./Diff.js";
|
|
18
|
-
import { makeUnexpectedError } from "./Error.js";
|
|
19
|
-
import { AppState, FlushSync } from "./Platform.js";
|
|
20
|
-
import { isSqlMutation, } from "./Sqlite.js";
|
|
21
|
-
import { makeStore } from "./Store.js";
|
|
22
|
-
import { initialSyncState } from "./Sync.js";
|
|
23
|
-
export class EvoluFactory extends Context.Tag("EvoluFactory")() {
|
|
24
|
-
}
|
|
25
|
-
EvoluFactory.Common = Layer.effect(EvoluFactory, Effect.gen(function* () {
|
|
26
|
-
const flushSync = yield* Effect.map(Effect.serviceOption(FlushSync), Option.getOrElse(() => (callback) => callback()));
|
|
27
|
-
const context = Context.empty().pipe(Context.add(DbFactory, yield* DbFactory), Context.add(NanoIdGenerator, yield* NanoIdGenerator), Context.add(FlushSync, flushSync), Context.add(AppState, yield* AppState));
|
|
28
|
-
// For hot/live reloading and future Evolu dynamic import.
|
|
29
|
-
const instances = new Map();
|
|
30
|
-
return EvoluFactory.of({
|
|
31
|
-
createEvolu: (schema, { indexes, initialData, mnemonic, ...config } = {}) => {
|
|
32
|
-
const runtime = createRuntime(config);
|
|
33
|
-
const name = config?.name || defaultConfig.name;
|
|
34
|
-
const dbSchema = {
|
|
35
|
-
tables: schemaToTables(schema),
|
|
36
|
-
indexes: indexes || [],
|
|
37
|
-
};
|
|
38
|
-
let evolu = instances.get(name);
|
|
39
|
-
if (evolu == null) {
|
|
40
|
-
evolu = createEvolu(dbSchema, runtime, initialData, mnemonic).pipe(Effect.provide(context), runtime.runSync);
|
|
41
|
-
instances.set(name, evolu);
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
evolu.ensureSchema(dbSchema);
|
|
45
|
-
}
|
|
46
|
-
return evolu;
|
|
47
|
-
},
|
|
48
|
-
});
|
|
49
|
-
}));
|
|
50
|
-
const schemaToTables = (schema) => pipe(getPropertySignatures(schema), Record.toEntries, Arr.map(([name, schema]) => ({
|
|
51
|
-
name,
|
|
52
|
-
columns: Object.keys(getPropertySignatures(schema)),
|
|
53
|
-
})));
|
|
54
|
-
// TODO: Simplify.
|
|
55
|
-
// https://discord.com/channels/795981131316985866/1218626687546294386/1218796529725476935
|
|
56
|
-
const getPropertySignatures = (schema) => {
|
|
57
|
-
const out = {};
|
|
58
|
-
const propertySignatures = AST.getPropertySignatures(schema.ast);
|
|
59
|
-
for (let i = 0; i < propertySignatures.length; i++) {
|
|
60
|
-
const propertySignature = propertySignatures[i];
|
|
61
|
-
out[propertySignature.name] = make(propertySignature.type);
|
|
62
|
-
}
|
|
63
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
64
|
-
return out;
|
|
65
|
-
};
|
|
66
|
-
const createEvolu = (schema, runtime, initialData, mnemonic) => Effect.gen(function* () {
|
|
67
|
-
yield* Effect.logTrace("EvoluFactory createEvolu");
|
|
68
|
-
const config = yield* Config;
|
|
69
|
-
const dbFactory = yield* DbFactory;
|
|
70
|
-
const appState = yield* AppState;
|
|
71
|
-
const nanoIdGenerator = yield* NanoIdGenerator;
|
|
72
|
-
const flushSync = yield* FlushSync;
|
|
73
|
-
const db = yield* dbFactory.createDb;
|
|
74
|
-
const errorStore = yield* makeStore(null);
|
|
75
|
-
const ownerStore = yield* makeStore(null);
|
|
76
|
-
const rowsStore = yield* makeStore(new Map());
|
|
77
|
-
const syncStateStore = yield* makeStore(initialSyncState);
|
|
78
|
-
const loadingPromises = new Map();
|
|
79
|
-
const subscribedQueries = new Map();
|
|
80
|
-
const handleAllErrors = (effect) => effect.pipe(Effect.catchAllDefect((error) => Effect.fail(makeUnexpectedError(error))), Effect.tapError(Effect.logError), Effect.tapError(errorStore.setState));
|
|
81
|
-
const runFork = flow(handleAllErrors, runtime.runFork);
|
|
82
|
-
const runSync = flow(handleAllErrors, runtime.runSync);
|
|
83
|
-
const runPromise = flow(handleAllErrors, runtime.runPromise);
|
|
84
|
-
const initialDataAsMutations = yield* Effect.provideService(initialDataToMutations(initialData), NanoIdGenerator, nanoIdGenerator);
|
|
85
|
-
const handleDbError = (error) => {
|
|
86
|
-
Effect.fail(error).pipe(runFork);
|
|
87
|
-
};
|
|
88
|
-
const handleSyncStateChange = (state) => {
|
|
89
|
-
Effect.logDebug(["Evolu handleSyncStateChange", { state }]).pipe(Effect.zipRight(syncStateStore.setState(state)), runFork);
|
|
90
|
-
};
|
|
91
|
-
const handleDbReceive = () => {
|
|
92
|
-
Effect.gen(function* () {
|
|
93
|
-
yield* Effect.logTrace("Evolu handleDbReceive");
|
|
94
|
-
releaseUnsubscribedLoadingPromises();
|
|
95
|
-
const queries = [...subscribedQueries.keys()];
|
|
96
|
-
if (queries.length > 0) {
|
|
97
|
-
yield* Effect.flatMap(db.loadQueries(queries), handlePatches());
|
|
98
|
-
}
|
|
99
|
-
}).pipe(runFork);
|
|
100
|
-
};
|
|
101
|
-
const sync = ({ refreshQueries }) => () => {
|
|
102
|
-
Effect.flatMap(db.sync(refreshQueries ? [...subscribedQueries.keys()] : []), handlePatches()).pipe(runFork);
|
|
103
|
-
};
|
|
104
|
-
db.init(schema, initialDataAsMutations, handleDbError, handleSyncStateChange, handleDbReceive, mnemonic).pipe(Effect.tap(sync({ refreshQueries: false })), Effect.flatMap(ownerStore.setState), Effect.catchTag("NotSupportedPlatformError", () => Effect.void), // no-op
|
|
105
|
-
runFork);
|
|
106
|
-
let socketResolved = false;
|
|
107
|
-
const socket = new Promise((resolve) => {
|
|
108
|
-
ownerStore.subscribe(() => {
|
|
109
|
-
const owner = ownerStore.getState();
|
|
110
|
-
if (!socketResolved && typeof owner?.id === "string") {
|
|
111
|
-
socketResolved = true;
|
|
112
|
-
resolve(createSocket(sync, config, owner));
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
const appStateReset = yield* appState.init({
|
|
117
|
-
onRequestSync: sync({ refreshQueries: true }),
|
|
118
|
-
reloadUrl: config.reloadUrl,
|
|
119
|
-
});
|
|
120
|
-
const handlePatches = (options) => (patches) => Effect.logDebug(["Evolu handlePatches", { patches }]).pipe(Effect.zipRight(rowsStoreStateFromPatches(patches)), Effect.tap((nextState) => Effect.forEach(patches, ({ query }) => resolveLoadingPromises(query, nextState.get(query) || emptyRows()))), Effect.tap((nextState) => {
|
|
121
|
-
if (options?.flushSync) {
|
|
122
|
-
flushSync(() => {
|
|
123
|
-
rowsStore.setState(nextState).pipe(runSync);
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
rowsStore.setState(nextState).pipe(runSync);
|
|
128
|
-
}
|
|
129
|
-
}));
|
|
130
|
-
const rowsStoreStateFromPatches = (patches) => Effect.sync(() => {
|
|
131
|
-
const rowsStoreState = rowsStore.getState();
|
|
132
|
-
if (patches.length === 0)
|
|
133
|
-
return rowsStoreState;
|
|
134
|
-
const queriesRows = Arr.map(patches, ({ query, patches }) => [
|
|
135
|
-
query,
|
|
136
|
-
applyPatches(patches, rowsStoreState.get(query) || emptyRows()),
|
|
137
|
-
]);
|
|
138
|
-
return new Map([...rowsStoreState, ...queriesRows]);
|
|
139
|
-
});
|
|
140
|
-
const resolveLoadingPromises = (query, rows) => Effect.sync(() => {
|
|
141
|
-
const loadingPromise = loadingPromises.get(query);
|
|
142
|
-
if (!loadingPromise)
|
|
143
|
-
return;
|
|
144
|
-
const result = queryResultFromRows(rows);
|
|
145
|
-
if (loadingPromise.promise.status !== "fulfilled") {
|
|
146
|
-
loadingPromise.resolve(result);
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
// A promise can't be fulfilled 2x, so we need a new one.
|
|
150
|
-
loadingPromise.promise = Promise.resolve(result);
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* "For example, a data framework can set the status and value fields on
|
|
154
|
-
* a promise preemptively, before passing to React, so that React can
|
|
155
|
-
* unwrap it without waiting a microtask."
|
|
156
|
-
* https://github.com/acdlite/rfcs/blob/first-class-promises/text/0000-first-class-support-for-promises.md
|
|
157
|
-
*/
|
|
158
|
-
Object.assign(loadingPromise.promise, {
|
|
159
|
-
status: "fulfilled",
|
|
160
|
-
value: result,
|
|
161
|
-
});
|
|
162
|
-
if (loadingPromise.releaseOnResolve) {
|
|
163
|
-
loadingPromises.delete(query);
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
/**
|
|
167
|
-
* We can't delete loading promises in `resolveLoadingPromises` because they
|
|
168
|
-
* must be cached, so repeated calls to `loadQuery` will always return the
|
|
169
|
-
* same promise until the data changes, and we also can't cache them forever
|
|
170
|
-
* because only subscribed queries are automatically updated (reactivity is
|
|
171
|
-
* expensive) hence this function must be called manually on any mutation.
|
|
172
|
-
*/
|
|
173
|
-
const releaseUnsubscribedLoadingPromises = () => {
|
|
174
|
-
[...loadingPromises.entries()]
|
|
175
|
-
.filter(([query]) => !subscribedQueries.has(query))
|
|
176
|
-
.forEach(([query, loadingPromise]) => {
|
|
177
|
-
if (loadingPromise.promise.status === "fulfilled") {
|
|
178
|
-
loadingPromises.delete(query);
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
loadingPromise.releaseOnResolve = true;
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
-
};
|
|
185
|
-
const mutate = (() => {
|
|
186
|
-
let queue = [];
|
|
187
|
-
return (table, { id, ...values }, onComplete) => {
|
|
188
|
-
Effect.logDebug(["Evolu mutate", { table, id, values }]).pipe(runSync);
|
|
189
|
-
const isInsert = id == null;
|
|
190
|
-
if (isInsert)
|
|
191
|
-
id = nanoIdGenerator.rowId.pipe(runSync);
|
|
192
|
-
queue = [...queue, [{ table, id, values, isInsert }, onComplete]];
|
|
193
|
-
if (queue.length === 1)
|
|
194
|
-
queueMicrotask(() => {
|
|
195
|
-
const [mutations, onCompletes] = Arr.unzip(queue);
|
|
196
|
-
queue = [];
|
|
197
|
-
const onCompletesDef = onCompletes.filter(Predicate.isNotUndefined);
|
|
198
|
-
releaseUnsubscribedLoadingPromises();
|
|
199
|
-
db.mutate(mutations, [...subscribedQueries.keys()]).pipe(Effect.flatMap(handlePatches({ flushSync: onCompletesDef.length > 0 })), Effect.tap(() => {
|
|
200
|
-
onCompletesDef.forEach((onComplete) => onComplete());
|
|
201
|
-
}), runFork);
|
|
202
|
-
});
|
|
203
|
-
return { id };
|
|
204
|
-
};
|
|
205
|
-
})();
|
|
206
|
-
const evolu = {
|
|
207
|
-
socket,
|
|
208
|
-
subscribeError: errorStore.subscribe,
|
|
209
|
-
getError: errorStore.getState,
|
|
210
|
-
createQuery: (queryCallback, options) => pipe(queryCallback(kysely).compile(), (compiledQuery) => {
|
|
211
|
-
if (isSqlMutation(compiledQuery.sql))
|
|
212
|
-
throw new Error("SQL mutation (INSERT, UPDATE, DELETE, etc.) isn't allowed in the Evolu `createQuery` function. Kysely suggests it because there is no read-only Kysely yet, and removing such an API is not possible. For mutations, use Evolu mutation API.");
|
|
213
|
-
const parameters = compiledQuery.parameters;
|
|
214
|
-
return {
|
|
215
|
-
sql: compiledQuery.sql,
|
|
216
|
-
parameters,
|
|
217
|
-
...(options && { options }),
|
|
218
|
-
};
|
|
219
|
-
}, (query) => serializeQuery(query)),
|
|
220
|
-
loadQuery: (() => {
|
|
221
|
-
let queue = [];
|
|
222
|
-
return (query) => {
|
|
223
|
-
Effect.logDebug([
|
|
224
|
-
"Evolu loadQuery",
|
|
225
|
-
{ query: deserializeQuery(query) },
|
|
226
|
-
]).pipe(runSync);
|
|
227
|
-
let loadingPromise = loadingPromises.get(query);
|
|
228
|
-
if (!loadingPromise) {
|
|
229
|
-
let resolve = constVoid;
|
|
230
|
-
const promise = new Promise((_resolve) => {
|
|
231
|
-
resolve = _resolve;
|
|
232
|
-
});
|
|
233
|
-
loadingPromise = { resolve, promise, releaseOnResolve: false };
|
|
234
|
-
loadingPromises.set(query, loadingPromise);
|
|
235
|
-
queue = [...queue, query];
|
|
236
|
-
if (queue.length === 1) {
|
|
237
|
-
queueMicrotask(() => {
|
|
238
|
-
db.loadQueries(Arr.dedupe(queue)).pipe(Effect.flatMap(handlePatches()), runFork);
|
|
239
|
-
queue = [];
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
return loadingPromise.promise;
|
|
244
|
-
};
|
|
245
|
-
})(),
|
|
246
|
-
loadQueries: (queries) => queries.map(evolu.loadQuery),
|
|
247
|
-
subscribeQuery: (query) => (listener) => {
|
|
248
|
-
subscribedQueries.set(query, Number.increment(subscribedQueries.get(query) ?? 0));
|
|
249
|
-
const unsubscribe = rowsStore.subscribe(listener);
|
|
250
|
-
return () => {
|
|
251
|
-
const count = subscribedQueries.get(query);
|
|
252
|
-
if (count != null && count > 1)
|
|
253
|
-
subscribedQueries.set(query, Number.decrement(count));
|
|
254
|
-
else
|
|
255
|
-
subscribedQueries.delete(query);
|
|
256
|
-
unsubscribe();
|
|
257
|
-
};
|
|
258
|
-
},
|
|
259
|
-
getQuery: (query) => queryResultFromRows(rowsStore.getState().get(query) || emptyRows()),
|
|
260
|
-
subscribeOwner: ownerStore.subscribe,
|
|
261
|
-
getOwner: ownerStore.getState,
|
|
262
|
-
subscribeSyncState: syncStateStore.subscribe,
|
|
263
|
-
getSyncState: syncStateStore.getState,
|
|
264
|
-
create: mutate,
|
|
265
|
-
update: mutate,
|
|
266
|
-
createOrUpdate: mutate,
|
|
267
|
-
resetOwner: (options) => Effect.gen(function* () {
|
|
268
|
-
yield* db.resetOwner();
|
|
269
|
-
if (options?.reload !== false)
|
|
270
|
-
yield* appStateReset.reset;
|
|
271
|
-
}).pipe(runPromise),
|
|
272
|
-
restoreOwner: (mnemonic, options) => Effect.gen(function* () {
|
|
273
|
-
yield* db.restoreOwner(schema, mnemonic);
|
|
274
|
-
if (options?.reload !== false)
|
|
275
|
-
yield* appStateReset.reset;
|
|
276
|
-
}).pipe(runPromise),
|
|
277
|
-
reloadApp: () => {
|
|
278
|
-
appStateReset.reset.pipe(runFork);
|
|
279
|
-
},
|
|
280
|
-
ensureSchema: (schema) => {
|
|
281
|
-
db.ensureSchema(schema).pipe(runFork);
|
|
282
|
-
},
|
|
283
|
-
exportDatabase: () => db.exportDatabase().pipe(runPromise),
|
|
284
|
-
};
|
|
285
|
-
return evolu;
|
|
286
|
-
});
|
|
287
|
-
const initialDataToMutations = (initialData = constVoid) => Effect.map(NanoIdGenerator, (nanoIdGenerator) => {
|
|
288
|
-
const mutations = [];
|
|
289
|
-
const mutate = (table, { id, ...values }) => {
|
|
290
|
-
if (id == null)
|
|
291
|
-
id = nanoIdGenerator.rowId.pipe(Effect.runSync);
|
|
292
|
-
mutations.push({ isInsert: true, id, table: table, values });
|
|
293
|
-
return { id };
|
|
294
|
-
};
|
|
295
|
-
const evolu = {
|
|
296
|
-
create: mutate,
|
|
297
|
-
createOrUpdate: mutate,
|
|
298
|
-
};
|
|
299
|
-
initialData(evolu);
|
|
300
|
-
return mutations;
|
|
301
|
-
});
|
|
302
|
-
// https://kysely.dev/docs/recipes/splitting-query-building-and-execution
|
|
303
|
-
const kysely = new Kysely.Kysely({
|
|
304
|
-
dialect: {
|
|
305
|
-
createAdapter: () => new Kysely.SqliteAdapter(),
|
|
306
|
-
createDriver: () => new Kysely.DummyDriver(),
|
|
307
|
-
createIntrospector() {
|
|
308
|
-
// eslint-disable-next-line @typescript-eslint/only-throw-error
|
|
309
|
-
throw "Not implemeneted";
|
|
310
|
-
},
|
|
311
|
-
createQueryCompiler: () => new Kysely.SqliteQueryCompiler(),
|
|
312
|
-
},
|
|
313
|
-
});
|
|
314
|
-
const createIndex = kysely.schema.createIndex.bind(kysely.schema);
|
|
315
|
-
/**
|
|
316
|
-
* Create SQLite indexes.
|
|
317
|
-
*
|
|
318
|
-
* See https://www.evolu.dev/docs/indexes
|
|
319
|
-
*
|
|
320
|
-
* @example
|
|
321
|
-
* const indexes = createIndexes((create) => [
|
|
322
|
-
* create("indexTodoCreatedAt").on("todo").column("createdAt"),
|
|
323
|
-
* create("indexTodoCategoryCreatedAt")
|
|
324
|
-
* .on("todoCategory")
|
|
325
|
-
* .column("createdAt"),
|
|
326
|
-
* ]);
|
|
327
|
-
*/
|
|
328
|
-
export const createIndexes = (callback) => callback(createIndex).map((index) => ({
|
|
329
|
-
name: index.toOperationNode().name.name,
|
|
330
|
-
sql: index.compile().sql,
|
|
331
|
-
}));
|
|
332
|
-
/** Create a namespaced lock name. */
|
|
333
|
-
export const getLockName = (name) => Effect.map(Config, (config) => `evolu:${config.name}:${name}`);
|
package/dist/src/Model.d.ts
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import * as S from "@effect/schema/Schema";
|
|
2
|
-
import * as Types from "effect/Types";
|
|
3
|
-
import { Value } from "./Sqlite.js";
|
|
4
|
-
/** Branded Id Schema. To create Id Schema for a specific table, use {@link id}. */
|
|
5
|
-
export declare const Id: S.brand<S.filter<S.Schema<string, string, never>>, "Id">;
|
|
6
|
-
export type Id = typeof Id.Type;
|
|
7
|
-
/**
|
|
8
|
-
* A factory function to create {@link Id} Schema for a specific table.
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* import * as S from "@effect/schema/Schema";
|
|
12
|
-
* import { id } from "@evolu/react";
|
|
13
|
-
*
|
|
14
|
-
* const TodoId = id("Todo");
|
|
15
|
-
* type TodoId = typeof TodoId.Type;
|
|
16
|
-
*/
|
|
17
|
-
export declare const id: <T extends string>(table: T) => S.brand<S.brand<S.Schema<string, string, never>, "Id">, T>;
|
|
18
|
-
/**
|
|
19
|
-
* SQLite doesn't support the Date type, so Evolu uses SqliteDate instead. Use
|
|
20
|
-
* the {@link cast} helper to cast SqliteDate from Date and back.
|
|
21
|
-
* https://www.sqlite.org/quirks.html#no_separate_datetime_datatype
|
|
22
|
-
*/
|
|
23
|
-
export declare const SqliteDate: S.brand<S.filter<typeof S.String>, "SqliteDate">;
|
|
24
|
-
export type SqliteDate = typeof SqliteDate.Type;
|
|
25
|
-
/**
|
|
26
|
-
* SQLite doesn't support the boolean type, so Evolu uses SqliteBoolean instead.
|
|
27
|
-
* Use the {@link cast} helper to cast SqliteBoolean from boolean and back.
|
|
28
|
-
* https://www.sqlite.org/quirks.html#no_separate_boolean_datatype
|
|
29
|
-
*/
|
|
30
|
-
export declare const SqliteBoolean: S.brand<S.refine<0 | 1, S.Schema<number, number, never>>, "SqliteBoolean">;
|
|
31
|
-
export type SqliteBoolean = typeof SqliteBoolean.Type;
|
|
32
|
-
/**
|
|
33
|
-
* A helper for casting types not supported by SQLite. SQLite doesn't support
|
|
34
|
-
* Date nor Boolean types, so Evolu emulates them with {@link SqliteBoolean} and
|
|
35
|
-
* {@link SqliteDate}.
|
|
36
|
-
*
|
|
37
|
-
* @example
|
|
38
|
-
* const allTodosNotDeleted = evolu.createQuery((db) =>
|
|
39
|
-
* db
|
|
40
|
-
* .selectFrom("todo")
|
|
41
|
-
* .selectAll()
|
|
42
|
-
* // isDeleted is SqliteBoolean
|
|
43
|
-
* .where("isDeleted", "is not", Evolu.cast(true)),
|
|
44
|
-
* );
|
|
45
|
-
*/
|
|
46
|
-
export declare function cast(value: boolean): SqliteBoolean;
|
|
47
|
-
export declare function cast(value: SqliteBoolean): boolean;
|
|
48
|
-
export declare function cast(value: Date): SqliteDate;
|
|
49
|
-
export declare function cast(value: SqliteDate): Date;
|
|
50
|
-
interface EvoluTypeError<E extends string> {
|
|
51
|
-
readonly __evoluTypeError__: E;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Create table schema.
|
|
55
|
-
*
|
|
56
|
-
* Supported types are null, string, number, Uint8Array, JSON Object, and JSON
|
|
57
|
-
* Array. Use SqliteDate for dates and SqliteBoolean for booleans.
|
|
58
|
-
*
|
|
59
|
-
* Reserved columns are createdAt, updatedAt, isDeleted. Those columns are added
|
|
60
|
-
* by default.
|
|
61
|
-
*
|
|
62
|
-
* @example
|
|
63
|
-
* const TodoId = id("Todo");
|
|
64
|
-
* type TodoId = typeof TodoId.Type;
|
|
65
|
-
*
|
|
66
|
-
* const TodoTable = table({
|
|
67
|
-
* id: TodoId,
|
|
68
|
-
* title: NonEmptyString1000,
|
|
69
|
-
* isCompleted: S.nullable(SqliteBoolean),
|
|
70
|
-
* });
|
|
71
|
-
* type TodoTable = typeof TodoTable.Type;
|
|
72
|
-
*/
|
|
73
|
-
export declare const table: <Fields extends TableFields>(fields: Fields) => ValidateFieldsTypes<Fields> extends true ? ValidateFieldsNames<Fields> extends true ? ValidateFieldsHasId<Fields> extends true ? S.Schema<Types.Simplify<S.Struct.Type<Fields> & typeof ReservedColumns.Type>, Types.Simplify<S.Struct.Encoded<Fields> & typeof ReservedColumns.Encoded>> : EvoluTypeError<"table() called without id column."> : EvoluTypeError<"table() called with a reserved column. Reserved columns are createdAt, updatedAt, isDeleted. Those columns are added by default."> : EvoluTypeError<"table() called with unsupported type. Supported types are null, string, number, Uint8Array, JSON Object, and JSON Array. Use SqliteDate for dates and SqliteBoolean for booleans.">;
|
|
74
|
-
declare const ReservedColumns: S.Struct<{
|
|
75
|
-
createdAt: S.brand<S.filter<typeof S.String>, "SqliteDate">;
|
|
76
|
-
updatedAt: S.brand<S.filter<typeof S.String>, "SqliteDate">;
|
|
77
|
-
isDeleted: S.brand<S.refine<0 | 1, S.Schema<number, number, never>>, "SqliteBoolean">;
|
|
78
|
-
}>;
|
|
79
|
-
type TableFields = Record<string, S.Schema<any>>;
|
|
80
|
-
type ValidateFieldsTypes<Fields extends TableFields> = keyof Fields extends infer K ? K extends keyof Fields ? Fields[K] extends TableFields ? ValidateFieldsTypes<Fields[K]> : Fields[K] extends S.Schema<infer A, infer _I> ? A extends Value ? true : false : never : never : never;
|
|
81
|
-
type ValidateFieldsNames<Fields extends TableFields> = keyof Fields extends infer K ? K extends keyof Fields ? K extends "createdAt" | "updatedAt" | "isDeleted" ? false : true : never : never;
|
|
82
|
-
type ValidateFieldsHasId<Fields extends TableFields> = "id" extends keyof Fields ? true : false;
|
|
83
|
-
/**
|
|
84
|
-
* Create database schema.
|
|
85
|
-
*
|
|
86
|
-
* Tables with a name prefixed with _ are local-only, which means they are not
|
|
87
|
-
* synced. Local-only tables are useful for device-specific or temporal data.
|
|
88
|
-
*
|
|
89
|
-
* @example
|
|
90
|
-
* const Database = database({
|
|
91
|
-
* // A local-only table.
|
|
92
|
-
* _todo: TodoTable,
|
|
93
|
-
* todo: TodoTable,
|
|
94
|
-
* todoCategory: TodoCategoryTable,
|
|
95
|
-
* });
|
|
96
|
-
* type Database = typeof Database.Type;
|
|
97
|
-
*/
|
|
98
|
-
export declare const database: typeof S.Struct;
|
|
99
|
-
/**
|
|
100
|
-
* String schema represents a string that is not stringified JSON. Using String
|
|
101
|
-
* schema for strings stored in SQLite is crucial to ensure a stored string is
|
|
102
|
-
* not automatically parsed to a JSON object or array when retrieved. Use String
|
|
103
|
-
* schema for all string-based schemas.
|
|
104
|
-
*/
|
|
105
|
-
export declare const String: S.brand<S.filter<typeof S.String>, "String">;
|
|
106
|
-
export type String = typeof String.Type;
|
|
107
|
-
/**
|
|
108
|
-
* A string with a maximum length of 1000 characters.
|
|
109
|
-
*
|
|
110
|
-
* @example
|
|
111
|
-
* import * as S from "@effect/schema/Schema";
|
|
112
|
-
* import { String1000 } from "@evolu/react";
|
|
113
|
-
*
|
|
114
|
-
* S.decode(String1000)(value);
|
|
115
|
-
*/
|
|
116
|
-
export declare const String1000: S.brand<S.filter<S.Schema<string & import("effect/Brand").Brand<"String">, string, never>>, "String1000">;
|
|
117
|
-
export type String1000 = typeof String1000.Type;
|
|
118
|
-
/**
|
|
119
|
-
* A nonempty string with a maximum length of 1000 characters.
|
|
120
|
-
*
|
|
121
|
-
* @example
|
|
122
|
-
* import * as S from "@effect/schema/Schema";
|
|
123
|
-
* import { NonEmptyString1000 } from "@evolu/react";
|
|
124
|
-
*
|
|
125
|
-
* S.decode(NonEmptyString1000)(value);
|
|
126
|
-
*/
|
|
127
|
-
export declare const NonEmptyString1000: S.brand<S.filter<S.Schema<string & import("effect/Brand").Brand<"String">, string, never>>, "NonEmptyString1000">;
|
|
128
|
-
export type NonEmptyString1000 = typeof NonEmptyString1000.Type;
|
|
129
|
-
/**
|
|
130
|
-
* A positive integer.
|
|
131
|
-
*
|
|
132
|
-
* @example
|
|
133
|
-
* import * as S from "@effect/schema/Schema";
|
|
134
|
-
* import { PositiveInt } from "@evolu/react";
|
|
135
|
-
*
|
|
136
|
-
* S.decode(PositiveInt)(value);
|
|
137
|
-
*/
|
|
138
|
-
export declare const PositiveInt: S.brand<S.filter<S.Schema<number, number, never>>, "PositiveInt">;
|
|
139
|
-
export type PositiveInt = typeof PositiveInt.Type;
|
|
140
|
-
export {};
|
|
141
|
-
//# sourceMappingURL=Model.d.ts.map
|
package/dist/src/Model.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Model.d.ts","sourceRoot":"","sources":["../../src/Model.ts"],"names":[],"mappings":"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"}
|
package/dist/src/Model.js
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import * as S from "@effect/schema/Schema";
|
|
2
|
-
import { maybeJson } from "./Sqlite.js";
|
|
3
|
-
/** Branded Id Schema. To create Id Schema for a specific table, use {@link id}. */
|
|
4
|
-
export const Id = S.String.pipe(S.pattern(/^[\w-]{21}$/), S.brand("Id"));
|
|
5
|
-
/**
|
|
6
|
-
* A factory function to create {@link Id} Schema for a specific table.
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* import * as S from "@effect/schema/Schema";
|
|
10
|
-
* import { id } from "@evolu/react";
|
|
11
|
-
*
|
|
12
|
-
* const TodoId = id("Todo");
|
|
13
|
-
* type TodoId = typeof TodoId.Type;
|
|
14
|
-
*/
|
|
15
|
-
export const id = (table) => Id.pipe(S.brand(table));
|
|
16
|
-
/**
|
|
17
|
-
* SQLite doesn't support the Date type, so Evolu uses SqliteDate instead. Use
|
|
18
|
-
* the {@link cast} helper to cast SqliteDate from Date and back.
|
|
19
|
-
* https://www.sqlite.org/quirks.html#no_separate_datetime_datatype
|
|
20
|
-
*/
|
|
21
|
-
export const SqliteDate = S.String.pipe(S.filter((s) => !isNaN(Date.parse(s))), S.brand("SqliteDate"));
|
|
22
|
-
/**
|
|
23
|
-
* SQLite doesn't support the boolean type, so Evolu uses SqliteBoolean instead.
|
|
24
|
-
* Use the {@link cast} helper to cast SqliteBoolean from boolean and back.
|
|
25
|
-
* https://www.sqlite.org/quirks.html#no_separate_boolean_datatype
|
|
26
|
-
*/
|
|
27
|
-
export const SqliteBoolean = S.Number.pipe(S.int(), S.filter((s) => s === 0 || s === 1), S.brand("SqliteBoolean"));
|
|
28
|
-
export function cast(value) {
|
|
29
|
-
if (typeof value === "boolean")
|
|
30
|
-
return (value === true ? 1 : 0);
|
|
31
|
-
if (typeof value === "number")
|
|
32
|
-
return value === 1;
|
|
33
|
-
if (value instanceof Date)
|
|
34
|
-
return value.toISOString();
|
|
35
|
-
return new Date(value);
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Create table schema.
|
|
39
|
-
*
|
|
40
|
-
* Supported types are null, string, number, Uint8Array, JSON Object, and JSON
|
|
41
|
-
* Array. Use SqliteDate for dates and SqliteBoolean for booleans.
|
|
42
|
-
*
|
|
43
|
-
* Reserved columns are createdAt, updatedAt, isDeleted. Those columns are added
|
|
44
|
-
* by default.
|
|
45
|
-
*
|
|
46
|
-
* @example
|
|
47
|
-
* const TodoId = id("Todo");
|
|
48
|
-
* type TodoId = typeof TodoId.Type;
|
|
49
|
-
*
|
|
50
|
-
* const TodoTable = table({
|
|
51
|
-
* id: TodoId,
|
|
52
|
-
* title: NonEmptyString1000,
|
|
53
|
-
* isCompleted: S.nullable(SqliteBoolean),
|
|
54
|
-
* });
|
|
55
|
-
* type TodoTable = typeof TodoTable.Type;
|
|
56
|
-
*/
|
|
57
|
-
export const table = (fields) => S.Struct(fields).pipe(S.extend(ReservedColumns));
|
|
58
|
-
const ReservedColumns = S.Struct({
|
|
59
|
-
createdAt: SqliteDate,
|
|
60
|
-
updatedAt: SqliteDate,
|
|
61
|
-
isDeleted: SqliteBoolean,
|
|
62
|
-
});
|
|
63
|
-
/**
|
|
64
|
-
* Create database schema.
|
|
65
|
-
*
|
|
66
|
-
* Tables with a name prefixed with _ are local-only, which means they are not
|
|
67
|
-
* synced. Local-only tables are useful for device-specific or temporal data.
|
|
68
|
-
*
|
|
69
|
-
* @example
|
|
70
|
-
* const Database = database({
|
|
71
|
-
* // A local-only table.
|
|
72
|
-
* _todo: TodoTable,
|
|
73
|
-
* todo: TodoTable,
|
|
74
|
-
* todoCategory: TodoCategoryTable,
|
|
75
|
-
* });
|
|
76
|
-
* type Database = typeof Database.Type;
|
|
77
|
-
*/
|
|
78
|
-
export const database = S.Struct;
|
|
79
|
-
/**
|
|
80
|
-
* String schema represents a string that is not stringified JSON. Using String
|
|
81
|
-
* schema for strings stored in SQLite is crucial to ensure a stored string is
|
|
82
|
-
* not automatically parsed to a JSON object or array when retrieved. Use String
|
|
83
|
-
* schema for all string-based schemas.
|
|
84
|
-
*/
|
|
85
|
-
export const String = S.String.pipe(S.filter((s) => {
|
|
86
|
-
if (!maybeJson(s))
|
|
87
|
-
return true;
|
|
88
|
-
try {
|
|
89
|
-
JSON.parse(s);
|
|
90
|
-
}
|
|
91
|
-
catch (e) {
|
|
92
|
-
return true;
|
|
93
|
-
}
|
|
94
|
-
return false;
|
|
95
|
-
}, { message: () => "a string that is not stringified JSON" }), S.brand("String"));
|
|
96
|
-
/**
|
|
97
|
-
* A string with a maximum length of 1000 characters.
|
|
98
|
-
*
|
|
99
|
-
* @example
|
|
100
|
-
* import * as S from "@effect/schema/Schema";
|
|
101
|
-
* import { String1000 } from "@evolu/react";
|
|
102
|
-
*
|
|
103
|
-
* S.decode(String1000)(value);
|
|
104
|
-
*/
|
|
105
|
-
export const String1000 = String.pipe(S.maxLength(1000), S.brand("String1000"));
|
|
106
|
-
/**
|
|
107
|
-
* A nonempty string with a maximum length of 1000 characters.
|
|
108
|
-
*
|
|
109
|
-
* @example
|
|
110
|
-
* import * as S from "@effect/schema/Schema";
|
|
111
|
-
* import { NonEmptyString1000 } from "@evolu/react";
|
|
112
|
-
*
|
|
113
|
-
* S.decode(NonEmptyString1000)(value);
|
|
114
|
-
*/
|
|
115
|
-
export const NonEmptyString1000 = String.pipe(S.minLength(1), S.maxLength(1000), S.brand("NonEmptyString1000"));
|
|
116
|
-
/**
|
|
117
|
-
* A positive integer.
|
|
118
|
-
*
|
|
119
|
-
* @example
|
|
120
|
-
* import * as S from "@effect/schema/Schema";
|
|
121
|
-
* import { PositiveInt } from "@evolu/react";
|
|
122
|
-
*
|
|
123
|
-
* S.decode(PositiveInt)(value);
|
|
124
|
-
*/
|
|
125
|
-
export const PositiveInt = S.Number.pipe(S.int(), S.positive(), S.brand("PositiveInt"));
|
package/dist/src/Murmurhash.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Murmurhash.d.ts","sourceRoot":"","sources":["../../src/Murmurhash.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,UAAU,QAAS,MAAM,oBAAa,MAoElD,CAAC"}
|
package/dist/src/Murmurhash.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
// https://github.com/garycourt/murmurhash-js/blob/master/murmurhash3_gc.js
|
|
2
|
-
export const murmurhash = (key, seed = 0) => {
|
|
3
|
-
let h1, h1b, k1, i;
|
|
4
|
-
const remainder = key.length & 3; // key.length % 4
|
|
5
|
-
const bytes = key.length - remainder;
|
|
6
|
-
h1 = seed;
|
|
7
|
-
const c1 = 0xcc9e2d51;
|
|
8
|
-
const c2 = 0x1b873593;
|
|
9
|
-
i = 0;
|
|
10
|
-
while (i < bytes) {
|
|
11
|
-
k1 =
|
|
12
|
-
(key.charCodeAt(i) & 0xff) |
|
|
13
|
-
((key.charCodeAt(++i) & 0xff) << 8) |
|
|
14
|
-
((key.charCodeAt(++i) & 0xff) << 16) |
|
|
15
|
-
((key.charCodeAt(++i) & 0xff) << 24);
|
|
16
|
-
++i;
|
|
17
|
-
k1 =
|
|
18
|
-
((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
|
|
19
|
-
k1 = (k1 << 15) | (k1 >>> 17);
|
|
20
|
-
k1 =
|
|
21
|
-
((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
|
|
22
|
-
h1 ^= k1;
|
|
23
|
-
h1 = (h1 << 13) | (h1 >>> 19);
|
|
24
|
-
h1b =
|
|
25
|
-
((h1 & 0xffff) * 5 + ((((h1 >>> 16) * 5) & 0xffff) << 16)) & 0xffffffff;
|
|
26
|
-
h1 = (h1b & 0xffff) + 0x6b64 + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16);
|
|
27
|
-
}
|
|
28
|
-
k1 = 0;
|
|
29
|
-
switch (remainder) {
|
|
30
|
-
case 3:
|
|
31
|
-
k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;
|
|
32
|
-
// eslint-disable-next-line no-fallthrough
|
|
33
|
-
case 2:
|
|
34
|
-
k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;
|
|
35
|
-
// eslint-disable-next-line no-fallthrough
|
|
36
|
-
case 1:
|
|
37
|
-
k1 ^= key.charCodeAt(i) & 0xff;
|
|
38
|
-
k1 =
|
|
39
|
-
((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) &
|
|
40
|
-
0xffffffff;
|
|
41
|
-
k1 = (k1 << 15) | (k1 >>> 17);
|
|
42
|
-
k1 =
|
|
43
|
-
((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) &
|
|
44
|
-
0xffffffff;
|
|
45
|
-
h1 ^= k1;
|
|
46
|
-
}
|
|
47
|
-
h1 ^= key.length;
|
|
48
|
-
h1 ^= h1 >>> 16;
|
|
49
|
-
h1 =
|
|
50
|
-
((h1 & 0xffff) * 0x85ebca6b +
|
|
51
|
-
((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) &
|
|
52
|
-
0xffffffff;
|
|
53
|
-
h1 ^= h1 >>> 13;
|
|
54
|
-
h1 =
|
|
55
|
-
((h1 & 0xffff) * 0xc2b2ae35 +
|
|
56
|
-
((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16)) &
|
|
57
|
-
0xffffffff;
|
|
58
|
-
h1 ^= h1 >>> 16;
|
|
59
|
-
return h1 >>> 0;
|
|
60
|
-
};
|