@tursodatabase/sync 0.1.5 → 0.2.0-pre.10
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 +83 -18
- package/dist/promise.d.ts +43 -0
- package/dist/promise.d.ts.map +1 -0
- package/dist/promise.js +137 -0
- package/dist/promise.test.d.ts +2 -0
- package/dist/promise.test.d.ts.map +1 -0
- package/dist/promise.test.js +454 -0
- package/index.js +166 -50
- package/package.json +37 -48
- package/browser.js +0 -1
- package/dist/sync_engine.d.ts +0 -24
- package/dist/sync_engine.js +0 -152
package/dist/sync_engine.js
DELETED
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
import { SyncEngine } from '#entry-point';
|
|
3
|
-
import { Database } from '@tursodatabase/database';
|
|
4
|
-
const GENERATOR_RESUME_IO = 0;
|
|
5
|
-
const GENERATOR_RESUME_DONE = 1;
|
|
6
|
-
function trackPromise(p) {
|
|
7
|
-
let status = { promise: null, finished: false };
|
|
8
|
-
status.promise = p.finally(() => status.finished = true);
|
|
9
|
-
return status;
|
|
10
|
-
}
|
|
11
|
-
function timeoutMs(ms) {
|
|
12
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
13
|
-
}
|
|
14
|
-
async function read(opts, path) {
|
|
15
|
-
if (opts.isMemory) {
|
|
16
|
-
return opts.value;
|
|
17
|
-
}
|
|
18
|
-
if (typeof window === 'undefined') {
|
|
19
|
-
const { promises } = await import('node:fs');
|
|
20
|
-
try {
|
|
21
|
-
return await promises.readFile(path);
|
|
22
|
-
}
|
|
23
|
-
catch (error) {
|
|
24
|
-
if (error.code === 'ENOENT') {
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
27
|
-
throw error;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
const data = localStorage.getItem(path);
|
|
32
|
-
if (data != null) {
|
|
33
|
-
return new TextEncoder().encode(data);
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
async function write(opts, path, content) {
|
|
41
|
-
if (opts.isMemory) {
|
|
42
|
-
opts.value = content;
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
const data = new Uint8Array(content);
|
|
46
|
-
if (typeof window === 'undefined') {
|
|
47
|
-
const { promises } = await import('node:fs');
|
|
48
|
-
const unix = Math.floor(Date.now() / 1000);
|
|
49
|
-
const nonce = Math.floor(Math.random() * 1000000000);
|
|
50
|
-
const tmp = `${path}.tmp.${unix}.${nonce}`;
|
|
51
|
-
await promises.writeFile(tmp, data);
|
|
52
|
-
await promises.rename(tmp, path);
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
localStorage.setItem(path, new TextDecoder().decode(data));
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
async function process(opts, request) {
|
|
59
|
-
const requestType = request.request();
|
|
60
|
-
const completion = request.completion();
|
|
61
|
-
if (requestType.type == 'Http') {
|
|
62
|
-
try {
|
|
63
|
-
let headers = opts.headers;
|
|
64
|
-
if (requestType.headers != null && requestType.headers.length > 0) {
|
|
65
|
-
headers = { ...opts.headers };
|
|
66
|
-
for (let header of requestType.headers) {
|
|
67
|
-
headers[header[0]] = header[1];
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
const response = await fetch(`${opts.url}${requestType.path}`, {
|
|
71
|
-
method: requestType.method,
|
|
72
|
-
headers: headers,
|
|
73
|
-
body: requestType.body != null ? new Uint8Array(requestType.body) : null,
|
|
74
|
-
});
|
|
75
|
-
completion.status(response.status);
|
|
76
|
-
const reader = response.body.getReader();
|
|
77
|
-
while (true) {
|
|
78
|
-
const { done, value } = await reader.read();
|
|
79
|
-
if (done) {
|
|
80
|
-
completion.done();
|
|
81
|
-
break;
|
|
82
|
-
}
|
|
83
|
-
completion.push(value);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
catch (error) {
|
|
87
|
-
completion.poison(`fetch error: ${error}`);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
else if (requestType.type == 'FullRead') {
|
|
91
|
-
try {
|
|
92
|
-
const metadata = await read(opts.metadata, requestType.path);
|
|
93
|
-
if (metadata != null) {
|
|
94
|
-
completion.push(metadata);
|
|
95
|
-
}
|
|
96
|
-
completion.done();
|
|
97
|
-
}
|
|
98
|
-
catch (error) {
|
|
99
|
-
completion.poison(`metadata read error: ${error}`);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
else if (requestType.type == 'FullWrite') {
|
|
103
|
-
try {
|
|
104
|
-
await write(opts.metadata, requestType.path, requestType.content);
|
|
105
|
-
completion.done();
|
|
106
|
-
}
|
|
107
|
-
catch (error) {
|
|
108
|
-
completion.poison(`metadata write error: ${error}`);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
async function run(opts, engine, generator) {
|
|
113
|
-
let tasks = [];
|
|
114
|
-
while (generator.resume(null) !== GENERATOR_RESUME_DONE) {
|
|
115
|
-
for (let request = engine.protocolIo(); request != null; request = engine.protocolIo()) {
|
|
116
|
-
tasks.push(trackPromise(process(opts, request)));
|
|
117
|
-
}
|
|
118
|
-
const tasksRace = tasks.length == 0 ? Promise.resolve() : Promise.race([timeoutMs(opts.preemptionMs), ...tasks.map(t => t.promise)]);
|
|
119
|
-
await Promise.all([engine.ioLoopAsync(), tasksRace]);
|
|
120
|
-
tasks = tasks.filter(t => !t.finished);
|
|
121
|
-
}
|
|
122
|
-
return generator.take();
|
|
123
|
-
}
|
|
124
|
-
export async function connect(opts) {
|
|
125
|
-
const engine = new SyncEngine({
|
|
126
|
-
path: opts.path,
|
|
127
|
-
clientName: opts.clientName,
|
|
128
|
-
tablesIgnore: opts.tablesIgnore,
|
|
129
|
-
transform: opts.transform,
|
|
130
|
-
enableTracing: opts.enableTracing
|
|
131
|
-
});
|
|
132
|
-
const httpOpts = {
|
|
133
|
-
url: opts.url,
|
|
134
|
-
headers: {
|
|
135
|
-
...(opts.authToken != null && { "Authorization": `Bearer ${opts.authToken}` }),
|
|
136
|
-
...(opts.encryptionKey != null && { "x-turso-encryption-key": opts.encryptionKey })
|
|
137
|
-
},
|
|
138
|
-
metadata: opts.path == ':memory:' ? { isMemory: true, value: null } : { isMemory: false },
|
|
139
|
-
preemptionMs: 1,
|
|
140
|
-
};
|
|
141
|
-
await run(httpOpts, engine, engine.init());
|
|
142
|
-
const nativeDb = engine.open();
|
|
143
|
-
const db = Database.create();
|
|
144
|
-
db.initialize(nativeDb, opts.path, false);
|
|
145
|
-
db.sync = async function () { await run(httpOpts, engine, engine.sync()); };
|
|
146
|
-
db.pull = async function () { await run(httpOpts, engine, engine.pull()); };
|
|
147
|
-
db.push = async function () { await run(httpOpts, engine, engine.push()); };
|
|
148
|
-
db.checkpoint = async function () { await run(httpOpts, engine, engine.checkpoint()); };
|
|
149
|
-
db.stats = async function () { return (await run(httpOpts, engine, engine.stats())); };
|
|
150
|
-
return db;
|
|
151
|
-
}
|
|
152
|
-
export { Database };
|