mindoodb-app-sdk 0.0.41 → 0.0.43
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 +87 -1
- package/dist/appBundleManifest-B0xfpaXG.d.ts +62 -0
- package/dist/chunk-7RAKZZA6.js +1426 -0
- package/dist/chunk-LT4FK6LU.js +146 -0
- package/dist/index.d.ts +123 -3
- package/dist/index.js +292 -1170
- package/dist/testing/index.d.ts +10 -1
- package/dist/testing/index.js +85 -1
- package/dist/{types-B0zYIrv3.d.ts → types-DALNnPXo.d.ts} +122 -2
- package/dist/vite/index.d.ts +46 -0
- package/dist/vite/index.js +291 -0
- package/package.json +9 -4
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MINDOODB_APP_BUNDLE_ARCHIVE_FILE_NAME,
|
|
3
|
+
MINDOODB_APP_BUNDLE_MANIFEST_FILE_NAME,
|
|
4
|
+
MINDOODB_APP_BUNDLE_MANIFEST_FORMAT,
|
|
5
|
+
MINDOODB_APP_BUNDLE_MANIFEST_VERSION,
|
|
6
|
+
buildMindooDBAppBundleContentHashInput
|
|
7
|
+
} from "../chunk-LT4FK6LU.js";
|
|
8
|
+
|
|
9
|
+
// src/vite/index.ts
|
|
10
|
+
import { createHash } from "crypto";
|
|
11
|
+
import { readdir, readFile, writeFile } from "fs/promises";
|
|
12
|
+
import path from "path";
|
|
13
|
+
|
|
14
|
+
// src/vite/zip.ts
|
|
15
|
+
import { deflateRawSync } from "zlib";
|
|
16
|
+
var CRC32_TABLE = (() => {
|
|
17
|
+
const table = new Uint32Array(256);
|
|
18
|
+
for (let index = 0; index < 256; index += 1) {
|
|
19
|
+
let value = index;
|
|
20
|
+
for (let bit = 0; bit < 8; bit += 1) {
|
|
21
|
+
value = value & 1 ? 3988292384 ^ value >>> 1 : value >>> 1;
|
|
22
|
+
}
|
|
23
|
+
table[index] = value >>> 0;
|
|
24
|
+
}
|
|
25
|
+
return table;
|
|
26
|
+
})();
|
|
27
|
+
function crc32(data) {
|
|
28
|
+
let crc = 4294967295;
|
|
29
|
+
for (let index = 0; index < data.length; index += 1) {
|
|
30
|
+
crc = CRC32_TABLE[(crc ^ data[index]) & 255] ^ crc >>> 8;
|
|
31
|
+
}
|
|
32
|
+
return (crc ^ 4294967295) >>> 0;
|
|
33
|
+
}
|
|
34
|
+
var DOS_TIME = 0;
|
|
35
|
+
var DOS_DATE = 33;
|
|
36
|
+
var ZIP64_LIMIT = 4294967295;
|
|
37
|
+
var PRECOMPRESSED_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
38
|
+
".7z",
|
|
39
|
+
".avif",
|
|
40
|
+
".br",
|
|
41
|
+
".gif",
|
|
42
|
+
".gz",
|
|
43
|
+
".jpeg",
|
|
44
|
+
".jpg",
|
|
45
|
+
".mp3",
|
|
46
|
+
".mp4",
|
|
47
|
+
".ogg",
|
|
48
|
+
".png",
|
|
49
|
+
".webm",
|
|
50
|
+
".webp",
|
|
51
|
+
".woff",
|
|
52
|
+
".woff2",
|
|
53
|
+
".zip",
|
|
54
|
+
".zst"
|
|
55
|
+
]);
|
|
56
|
+
function isPrecompressedPath(filePath) {
|
|
57
|
+
const dotIndex = filePath.lastIndexOf(".");
|
|
58
|
+
if (dotIndex < 0) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
return PRECOMPRESSED_EXTENSIONS.has(filePath.slice(dotIndex).toLowerCase());
|
|
62
|
+
}
|
|
63
|
+
var LOCAL_HEADER_SIGNATURE = 67324752;
|
|
64
|
+
var CENTRAL_HEADER_SIGNATURE = 33639248;
|
|
65
|
+
var END_OF_CENTRAL_DIRECTORY_SIGNATURE = 101010256;
|
|
66
|
+
var UTF8_NAME_FLAG = 2048;
|
|
67
|
+
function createZipArchive(entries) {
|
|
68
|
+
const prepared = [];
|
|
69
|
+
const localChunks = [];
|
|
70
|
+
let offset = 0;
|
|
71
|
+
for (const entry of entries) {
|
|
72
|
+
const nameBytes = Buffer.from(entry.path, "utf8");
|
|
73
|
+
const data = Buffer.from(entry.data.buffer, entry.data.byteOffset, entry.data.byteLength);
|
|
74
|
+
const store = isPrecompressedPath(entry.path);
|
|
75
|
+
const deflated = store ? null : deflateRawSync(data, { level: 9 });
|
|
76
|
+
const useStored = !deflated || deflated.length >= data.length;
|
|
77
|
+
const payload = useStored ? data : deflated;
|
|
78
|
+
if (data.length > ZIP64_LIMIT || payload.length > ZIP64_LIMIT) {
|
|
79
|
+
throw new Error(`Bundle file "${entry.path}" exceeds the 4 GiB ZIP limit.`);
|
|
80
|
+
}
|
|
81
|
+
const header = Buffer.alloc(30);
|
|
82
|
+
header.writeUInt32LE(LOCAL_HEADER_SIGNATURE, 0);
|
|
83
|
+
header.writeUInt16LE(20, 4);
|
|
84
|
+
header.writeUInt16LE(UTF8_NAME_FLAG, 6);
|
|
85
|
+
header.writeUInt16LE(useStored ? 0 : 8, 8);
|
|
86
|
+
header.writeUInt16LE(DOS_TIME, 10);
|
|
87
|
+
header.writeUInt16LE(DOS_DATE, 12);
|
|
88
|
+
const crc = crc32(data);
|
|
89
|
+
header.writeUInt32LE(crc, 14);
|
|
90
|
+
header.writeUInt32LE(payload.length, 18);
|
|
91
|
+
header.writeUInt32LE(data.length, 22);
|
|
92
|
+
header.writeUInt16LE(nameBytes.length, 26);
|
|
93
|
+
header.writeUInt16LE(0, 28);
|
|
94
|
+
localChunks.push(header, nameBytes, payload);
|
|
95
|
+
prepared.push({
|
|
96
|
+
nameBytes,
|
|
97
|
+
payload,
|
|
98
|
+
method: useStored ? 0 : 8,
|
|
99
|
+
crc,
|
|
100
|
+
uncompressedSize: data.length,
|
|
101
|
+
localHeaderOffset: offset
|
|
102
|
+
});
|
|
103
|
+
offset += header.length + nameBytes.length + payload.length;
|
|
104
|
+
if (offset > ZIP64_LIMIT) {
|
|
105
|
+
throw new Error("Bundle archive exceeds the 4 GiB ZIP limit.");
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const centralChunks = [];
|
|
109
|
+
let centralDirectorySize = 0;
|
|
110
|
+
for (const entry of prepared) {
|
|
111
|
+
const header = Buffer.alloc(46);
|
|
112
|
+
header.writeUInt32LE(CENTRAL_HEADER_SIGNATURE, 0);
|
|
113
|
+
header.writeUInt16LE(20, 4);
|
|
114
|
+
header.writeUInt16LE(20, 6);
|
|
115
|
+
header.writeUInt16LE(UTF8_NAME_FLAG, 8);
|
|
116
|
+
header.writeUInt16LE(entry.method, 10);
|
|
117
|
+
header.writeUInt16LE(DOS_TIME, 12);
|
|
118
|
+
header.writeUInt16LE(DOS_DATE, 14);
|
|
119
|
+
header.writeUInt32LE(entry.crc, 16);
|
|
120
|
+
header.writeUInt32LE(entry.payload.length, 20);
|
|
121
|
+
header.writeUInt32LE(entry.uncompressedSize, 24);
|
|
122
|
+
header.writeUInt16LE(entry.nameBytes.length, 28);
|
|
123
|
+
header.writeUInt16LE(0, 30);
|
|
124
|
+
header.writeUInt16LE(0, 32);
|
|
125
|
+
header.writeUInt16LE(0, 34);
|
|
126
|
+
header.writeUInt16LE(0, 36);
|
|
127
|
+
header.writeUInt32LE(0, 38);
|
|
128
|
+
header.writeUInt32LE(entry.localHeaderOffset, 42);
|
|
129
|
+
centralChunks.push(header, entry.nameBytes);
|
|
130
|
+
centralDirectorySize += header.length + entry.nameBytes.length;
|
|
131
|
+
}
|
|
132
|
+
if (prepared.length > 65535) {
|
|
133
|
+
throw new Error("Bundle archive exceeds the 65535 entry ZIP limit.");
|
|
134
|
+
}
|
|
135
|
+
const endRecord = Buffer.alloc(22);
|
|
136
|
+
endRecord.writeUInt32LE(END_OF_CENTRAL_DIRECTORY_SIGNATURE, 0);
|
|
137
|
+
endRecord.writeUInt16LE(0, 4);
|
|
138
|
+
endRecord.writeUInt16LE(0, 6);
|
|
139
|
+
endRecord.writeUInt16LE(prepared.length, 8);
|
|
140
|
+
endRecord.writeUInt16LE(prepared.length, 10);
|
|
141
|
+
endRecord.writeUInt32LE(centralDirectorySize, 12);
|
|
142
|
+
endRecord.writeUInt32LE(offset, 16);
|
|
143
|
+
endRecord.writeUInt16LE(0, 20);
|
|
144
|
+
return Buffer.concat([...localChunks, ...centralChunks, endRecord]);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// src/vite/index.ts
|
|
148
|
+
var DEFAULT_EXCLUDED_ROOT_FILES = /* @__PURE__ */ new Set([
|
|
149
|
+
"sw.js",
|
|
150
|
+
"sw.js.map",
|
|
151
|
+
"registerSW.js",
|
|
152
|
+
"_headers",
|
|
153
|
+
"_redirects",
|
|
154
|
+
MINDOODB_APP_BUNDLE_MANIFEST_FILE_NAME,
|
|
155
|
+
MINDOODB_APP_BUNDLE_ARCHIVE_FILE_NAME
|
|
156
|
+
]);
|
|
157
|
+
var WORKBOX_RUNTIME_PATTERN = /^workbox-[a-z0-9]+\.js(\.map)?$/i;
|
|
158
|
+
function sha256(data) {
|
|
159
|
+
return `sha256-${createHash("sha256").update(data).digest("hex")}`;
|
|
160
|
+
}
|
|
161
|
+
async function collectFiles(rootDir) {
|
|
162
|
+
const collected = [];
|
|
163
|
+
async function walk(currentDir, prefix) {
|
|
164
|
+
const entries = await readdir(currentDir, { withFileTypes: true });
|
|
165
|
+
for (const entry of entries) {
|
|
166
|
+
const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
167
|
+
if (entry.isDirectory()) {
|
|
168
|
+
await walk(path.join(currentDir, entry.name), relativePath);
|
|
169
|
+
} else if (entry.isFile()) {
|
|
170
|
+
collected.push(relativePath);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
await walk(rootDir, "");
|
|
175
|
+
return collected.sort();
|
|
176
|
+
}
|
|
177
|
+
function isExcluded(relativePath, options) {
|
|
178
|
+
const isRootLevel = !relativePath.includes("/");
|
|
179
|
+
if (isRootLevel && DEFAULT_EXCLUDED_ROOT_FILES.has(relativePath)) {
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
if (isRootLevel && WORKBOX_RUNTIME_PATTERN.test(relativePath)) {
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
if (options.excludeSourcemaps !== false && relativePath.toLowerCase().endsWith(".map")) {
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
return options.exclude?.(relativePath) === true;
|
|
189
|
+
}
|
|
190
|
+
function resolveEntryPath(paths, configured) {
|
|
191
|
+
if (configured) {
|
|
192
|
+
const normalized = configured.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
193
|
+
if (!paths.includes(normalized)) {
|
|
194
|
+
throw new Error(`[haven-bundle] Configured entry "${configured}" is not part of the build output.`);
|
|
195
|
+
}
|
|
196
|
+
return normalized;
|
|
197
|
+
}
|
|
198
|
+
const preferred = paths.find((candidate) => candidate.toLowerCase() === "index.html");
|
|
199
|
+
if (preferred) {
|
|
200
|
+
return preferred;
|
|
201
|
+
}
|
|
202
|
+
const nested = paths.find((candidate) => candidate.toLowerCase().endsWith("/index.html"));
|
|
203
|
+
if (nested) {
|
|
204
|
+
return nested;
|
|
205
|
+
}
|
|
206
|
+
const firstHtml = paths.find((candidate) => candidate.toLowerCase().endsWith(".html"));
|
|
207
|
+
if (firstHtml) {
|
|
208
|
+
return firstHtml;
|
|
209
|
+
}
|
|
210
|
+
throw new Error("[haven-bundle] The build output does not contain an HTML entry file.");
|
|
211
|
+
}
|
|
212
|
+
async function readPackageMetadata(root) {
|
|
213
|
+
try {
|
|
214
|
+
const raw = await readFile(path.join(root, "package.json"), "utf8");
|
|
215
|
+
const parsed = JSON.parse(raw);
|
|
216
|
+
return {
|
|
217
|
+
name: typeof parsed.name === "string" ? parsed.name : void 0,
|
|
218
|
+
version: typeof parsed.version === "string" ? parsed.version : void 0
|
|
219
|
+
};
|
|
220
|
+
} catch {
|
|
221
|
+
return { name: void 0, version: void 0 };
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
function havenBundle(options = {}) {
|
|
225
|
+
let resolvedConfig = null;
|
|
226
|
+
return {
|
|
227
|
+
name: "haven-bundle",
|
|
228
|
+
apply: "build",
|
|
229
|
+
configResolved(config) {
|
|
230
|
+
resolvedConfig = config;
|
|
231
|
+
},
|
|
232
|
+
async closeBundle() {
|
|
233
|
+
if (!resolvedConfig) {
|
|
234
|
+
throw new Error("[haven-bundle] Plugin ran without a resolved Vite config.");
|
|
235
|
+
}
|
|
236
|
+
const outDir = path.resolve(resolvedConfig.root, resolvedConfig.build.outDir);
|
|
237
|
+
const allPaths = await collectFiles(outDir);
|
|
238
|
+
const bundlePaths = allPaths.filter((candidate) => !isExcluded(candidate, options));
|
|
239
|
+
if (!bundlePaths.length) {
|
|
240
|
+
throw new Error(`[haven-bundle] No bundle files found in "${outDir}".`);
|
|
241
|
+
}
|
|
242
|
+
const entry = resolveEntryPath(bundlePaths, options.entry);
|
|
243
|
+
const packageMetadata = await readPackageMetadata(resolvedConfig.root);
|
|
244
|
+
const appId = options.appId ?? packageMetadata.name;
|
|
245
|
+
const version = options.version ?? packageMetadata.version;
|
|
246
|
+
if (!appId) {
|
|
247
|
+
throw new Error("[haven-bundle] Unable to determine appId \u2014 pass it explicitly.");
|
|
248
|
+
}
|
|
249
|
+
if (!version) {
|
|
250
|
+
throw new Error("[haven-bundle] Unable to determine version \u2014 pass it explicitly.");
|
|
251
|
+
}
|
|
252
|
+
const files = [];
|
|
253
|
+
const archiveEntries = [];
|
|
254
|
+
for (const relativePath of bundlePaths) {
|
|
255
|
+
const data = await readFile(path.join(outDir, relativePath));
|
|
256
|
+
files.push({ path: relativePath, hash: sha256(data), size: data.byteLength });
|
|
257
|
+
archiveEntries.push({ path: relativePath, data });
|
|
258
|
+
}
|
|
259
|
+
const archive = createZipArchive(archiveEntries);
|
|
260
|
+
const manifest = {
|
|
261
|
+
format: MINDOODB_APP_BUNDLE_MANIFEST_FORMAT,
|
|
262
|
+
formatVersion: MINDOODB_APP_BUNDLE_MANIFEST_VERSION,
|
|
263
|
+
appId,
|
|
264
|
+
version,
|
|
265
|
+
entry,
|
|
266
|
+
archive: {
|
|
267
|
+
path: MINDOODB_APP_BUNDLE_ARCHIVE_FILE_NAME,
|
|
268
|
+
hash: sha256(archive),
|
|
269
|
+
size: archive.byteLength
|
|
270
|
+
},
|
|
271
|
+
contentHash: sha256(buildMindooDBAppBundleContentHashInput(files)),
|
|
272
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
273
|
+
files
|
|
274
|
+
};
|
|
275
|
+
await writeFile(path.join(outDir, MINDOODB_APP_BUNDLE_ARCHIVE_FILE_NAME), archive);
|
|
276
|
+
await writeFile(
|
|
277
|
+
path.join(outDir, MINDOODB_APP_BUNDLE_MANIFEST_FILE_NAME),
|
|
278
|
+
`${JSON.stringify(manifest, null, 2)}
|
|
279
|
+
`,
|
|
280
|
+
"utf8"
|
|
281
|
+
);
|
|
282
|
+
const totalBytes = files.reduce((sum, file) => sum + file.size, 0);
|
|
283
|
+
console.log(
|
|
284
|
+
`[haven-bundle] ${files.length} files (${(totalBytes / 1024 / 1024).toFixed(2)} MB) \u2192 ${MINDOODB_APP_BUNDLE_ARCHIVE_FILE_NAME} (${(archive.byteLength / 1024 / 1024).toFixed(2)} MB), contentHash ${manifest.contentHash.slice(7, 19)}`
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
export {
|
|
290
|
+
havenBundle
|
|
291
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mindoodb-app-sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.43",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=22.13.0"
|
|
6
6
|
},
|
|
@@ -33,6 +33,11 @@
|
|
|
33
33
|
"types": "./dist/testing/index.d.ts",
|
|
34
34
|
"import": "./dist/testing/index.js",
|
|
35
35
|
"default": "./dist/testing/index.js"
|
|
36
|
+
},
|
|
37
|
+
"./vite": {
|
|
38
|
+
"types": "./dist/vite/index.d.ts",
|
|
39
|
+
"import": "./dist/vite/index.js",
|
|
40
|
+
"default": "./dist/vite/index.js"
|
|
36
41
|
}
|
|
37
42
|
},
|
|
38
43
|
"dependencies": {
|
|
@@ -40,7 +45,7 @@
|
|
|
40
45
|
},
|
|
41
46
|
"peerDependencies": {
|
|
42
47
|
"@automerge/automerge": "^3.3.2",
|
|
43
|
-
"mindoodb": ">=0.0.
|
|
48
|
+
"mindoodb": ">=0.0.58"
|
|
44
49
|
},
|
|
45
50
|
"peerDependenciesMeta": {
|
|
46
51
|
"@automerge/automerge": {
|
|
@@ -52,14 +57,14 @@
|
|
|
52
57
|
},
|
|
53
58
|
"devDependencies": {
|
|
54
59
|
"@automerge/automerge": "^3.3.2",
|
|
55
|
-
"mindoodb": "^0.0.
|
|
60
|
+
"mindoodb": "^0.0.58",
|
|
56
61
|
"@types/node": "25.5.0",
|
|
57
62
|
"tsup": "^8.5.1",
|
|
58
63
|
"typescript": "^6.0.2",
|
|
59
64
|
"vitest": "^4.1.2"
|
|
60
65
|
},
|
|
61
66
|
"scripts": {
|
|
62
|
-
"build": "tsup src/index.ts src/testing/index.ts --format esm --dts --clean --external @automerge/automerge --external mindoodb --tsconfig tsconfig.build.json",
|
|
67
|
+
"build": "tsup src/index.ts src/testing/index.ts src/vite/index.ts --format esm --dts --clean --external @automerge/automerge --external mindoodb --tsconfig tsconfig.build.json",
|
|
63
68
|
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
64
69
|
"test": "vitest run",
|
|
65
70
|
"test:watch": "vitest"
|