orez 0.0.9 → 0.0.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.
@@ -0,0 +1,11 @@
1
+ /**
2
+ * minimal local bunny cdn storage-compatible server.
3
+ * handles GET/PUT/DELETE/HEAD and directory listing.
4
+ */
5
+ import { type Server } from 'node:http';
6
+ export interface BunnyLocalConfig {
7
+ port: number;
8
+ dataDir: string;
9
+ }
10
+ export declare function startBunnyLocal(config: BunnyLocalConfig): Promise<Server>;
11
+ //# sourceMappingURL=bunny-local.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bunny-local.d.ts","sourceRoot":"","sources":["../src/bunny-local.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,OAAO,EAEL,KAAK,MAAM,EAGZ,MAAM,WAAW,CAAA;AAKlB,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAqED,wBAAgB,eAAe,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CA+HzE"}
@@ -0,0 +1,175 @@
1
+ /**
2
+ * minimal local bunny cdn storage-compatible server.
3
+ * handles GET/PUT/DELETE/HEAD and directory listing.
4
+ */
5
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, statSync, readdirSync, } from 'node:fs';
6
+ import { createServer, } from 'node:http';
7
+ import { join, dirname, extname, relative } from 'node:path';
8
+ import { log } from './log.js';
9
+ const MIME_TYPES = {
10
+ '.jpg': 'image/jpeg',
11
+ '.jpeg': 'image/jpeg',
12
+ '.png': 'image/png',
13
+ '.gif': 'image/gif',
14
+ '.webp': 'image/webp',
15
+ '.svg': 'image/svg+xml',
16
+ '.json': 'application/json',
17
+ '.txt': 'text/plain',
18
+ '.pdf': 'application/pdf',
19
+ '.mp4': 'video/mp4',
20
+ '.mp3': 'audio/mpeg',
21
+ '.css': 'text/css',
22
+ '.js': 'application/javascript',
23
+ '.html': 'text/html',
24
+ '.woff': 'font/woff',
25
+ '.woff2': 'font/woff2',
26
+ '.ttf': 'font/ttf',
27
+ '.otf': 'font/otf',
28
+ };
29
+ function corsHeaders() {
30
+ return {
31
+ 'Access-Control-Allow-Origin': '*',
32
+ 'Access-Control-Allow-Methods': 'GET, PUT, DELETE, HEAD, OPTIONS',
33
+ 'Access-Control-Allow-Headers': '*',
34
+ 'Access-Control-Expose-Headers': 'Content-Length',
35
+ };
36
+ }
37
+ // recursively collect files for directory listing
38
+ function listFiles(dir, baseDir) {
39
+ if (!existsSync(dir) || !statSync(dir).isDirectory()) {
40
+ return [];
41
+ }
42
+ const entries = readdirSync(dir, { withFileTypes: true });
43
+ return entries.map((entry) => {
44
+ const fullPath = join(dir, entry.name);
45
+ const stat = statSync(fullPath);
46
+ const relativePath = '/' + relative(baseDir, dir) + '/';
47
+ return {
48
+ Guid: '00000000-0000-0000-0000-000000000000',
49
+ StorageZoneName: '',
50
+ Path: relativePath,
51
+ ObjectName: entry.name,
52
+ Length: entry.isDirectory() ? 0 : stat.size,
53
+ LastChanged: stat.mtime.toISOString(),
54
+ IsDirectory: entry.isDirectory(),
55
+ DateCreated: stat.birthtime.toISOString(),
56
+ };
57
+ });
58
+ }
59
+ export function startBunnyLocal(config) {
60
+ const storageDir = join(config.dataDir, 'bunny');
61
+ mkdirSync(storageDir, { recursive: true });
62
+ const server = createServer((req, res) => {
63
+ const headers = corsHeaders();
64
+ if (req.method === 'OPTIONS') {
65
+ res.writeHead(200, headers);
66
+ res.end();
67
+ return;
68
+ }
69
+ const url = new URL(req.url || '/', `http://localhost:${config.port}`);
70
+ // sanitize path to prevent traversal
71
+ const normalized = url.pathname
72
+ .split('/')
73
+ .filter((s) => s && s !== '..' && s !== '.')
74
+ .join('/');
75
+ const filePath = join(storageDir, normalized);
76
+ if (!filePath.startsWith(storageDir)) {
77
+ res.writeHead(403, headers);
78
+ res.end();
79
+ return;
80
+ }
81
+ try {
82
+ switch (req.method) {
83
+ case 'GET': {
84
+ // directory listing if path ends with / or is a directory
85
+ if (url.pathname.endsWith('/') ||
86
+ (existsSync(filePath) && statSync(filePath).isDirectory())) {
87
+ const items = listFiles(filePath, storageDir);
88
+ const body = JSON.stringify(items);
89
+ res.writeHead(200, {
90
+ ...headers,
91
+ 'Content-Type': 'application/json',
92
+ });
93
+ res.end(body);
94
+ return;
95
+ }
96
+ if (!existsSync(filePath)) {
97
+ res.writeHead(404, { ...headers, 'Content-Type': 'application/json' });
98
+ res.end(JSON.stringify({ HttpCode: 404, Message: 'Object Not Found' }));
99
+ return;
100
+ }
101
+ const data = readFileSync(filePath);
102
+ const ext = extname(filePath);
103
+ const contentType = MIME_TYPES[ext] || 'application/octet-stream';
104
+ res.writeHead(200, {
105
+ ...headers,
106
+ 'Content-Type': contentType,
107
+ 'Content-Length': data.length.toString(),
108
+ });
109
+ res.end(data);
110
+ break;
111
+ }
112
+ case 'PUT': {
113
+ const chunks = [];
114
+ req.on('data', (chunk) => chunks.push(chunk));
115
+ req.on('end', () => {
116
+ mkdirSync(dirname(filePath), { recursive: true });
117
+ const body = Buffer.concat(chunks);
118
+ writeFileSync(filePath, body);
119
+ res.writeHead(201, {
120
+ ...headers,
121
+ 'Content-Type': 'application/json',
122
+ });
123
+ res.end(JSON.stringify({ HttpCode: 201, Message: 'File uploaded.' }));
124
+ });
125
+ break;
126
+ }
127
+ case 'DELETE': {
128
+ if (existsSync(filePath)) {
129
+ unlinkSync(filePath);
130
+ }
131
+ res.writeHead(200, {
132
+ ...headers,
133
+ 'Content-Type': 'application/json',
134
+ });
135
+ res.end(JSON.stringify({ HttpCode: 200, Message: 'File deleted successfuly.' }));
136
+ break;
137
+ }
138
+ case 'HEAD': {
139
+ if (!existsSync(filePath) || statSync(filePath).isDirectory()) {
140
+ res.writeHead(404, headers);
141
+ res.end();
142
+ return;
143
+ }
144
+ const stat = statSync(filePath);
145
+ const ext2 = extname(filePath);
146
+ res.writeHead(200, {
147
+ ...headers,
148
+ 'Content-Type': MIME_TYPES[ext2] || 'application/octet-stream',
149
+ 'Content-Length': stat.size.toString(),
150
+ });
151
+ res.end();
152
+ break;
153
+ }
154
+ default:
155
+ res.writeHead(405, headers);
156
+ res.end();
157
+ }
158
+ }
159
+ catch {
160
+ res.writeHead(500, {
161
+ ...headers,
162
+ 'Content-Type': 'application/json',
163
+ });
164
+ res.end(JSON.stringify({ HttpCode: 500, Message: 'Internal Server Error' }));
165
+ }
166
+ });
167
+ return new Promise((resolve, reject) => {
168
+ server.listen(config.port, '127.0.0.1', () => {
169
+ log.bunny(`listening on port ${config.port}`);
170
+ resolve(server);
171
+ });
172
+ server.on('error', reject);
173
+ });
174
+ }
175
+ //# sourceMappingURL=bunny-local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bunny-local.js","sourceRoot":"","sources":["../src/bunny-local.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -2,7 +2,6 @@
2
2
  import { defineCommand, runMain } from 'citty';
3
3
  import { startZeroLite } from './index.js';
4
4
  import { log } from './log.js';
5
- import { startS3Local } from './s3-local.js';
6
5
  const s3Command = defineCommand({
7
6
  meta: {
8
7
  name: 's3',
@@ -21,6 +20,7 @@ const s3Command = defineCommand({
21
20
  },
22
21
  },
23
22
  async run({ args }) {
23
+ const { startS3Local } = await import('./s3-local.js');
24
24
  const server = await startS3Local({
25
25
  port: Number(args.port),
26
26
  dataDir: args['data-dir'],
@@ -35,6 +35,39 @@ const s3Command = defineCommand({
35
35
  });
36
36
  },
37
37
  });
38
+ const bunnyCommand = defineCommand({
39
+ meta: {
40
+ name: 'bunny',
41
+ description: 'start a local bunny cdn storage-compatible server',
42
+ },
43
+ args: {
44
+ port: {
45
+ type: 'string',
46
+ description: 'port to listen on',
47
+ default: '3533',
48
+ },
49
+ 'data-dir': {
50
+ type: 'string',
51
+ description: 'data directory for stored files',
52
+ default: '.orez',
53
+ },
54
+ },
55
+ async run({ args }) {
56
+ const { startBunnyLocal } = await import('./bunny-local.js');
57
+ const server = await startBunnyLocal({
58
+ port: Number(args.port),
59
+ dataDir: args['data-dir'],
60
+ });
61
+ process.on('SIGINT', () => {
62
+ server.close();
63
+ process.exit(0);
64
+ });
65
+ process.on('SIGTERM', () => {
66
+ server.close();
67
+ process.exit(0);
68
+ });
69
+ },
70
+ });
38
71
  const main = defineCommand({
39
72
  meta: {
40
73
  name: 'orez',
@@ -96,9 +129,20 @@ const main = defineCommand({
96
129
  description: 's3 server port',
97
130
  default: '9200',
98
131
  },
132
+ bunny: {
133
+ type: 'boolean',
134
+ description: 'also start a local bunny cdn storage-compatible server',
135
+ default: false,
136
+ },
137
+ 'bunny-port': {
138
+ type: 'string',
139
+ description: 'bunny storage server port',
140
+ default: '3533',
141
+ },
99
142
  },
100
143
  subCommands: {
101
144
  s3: s3Command,
145
+ bunny: bunnyCommand,
102
146
  },
103
147
  async run({ args }) {
104
148
  const { config, stop } = await startZeroLite({
@@ -114,22 +158,33 @@ const main = defineCommand({
114
158
  });
115
159
  let s3Server = null;
116
160
  if (args.s3) {
161
+ const { startS3Local } = await import('./s3-local.js');
117
162
  s3Server = await startS3Local({
118
163
  port: Number(args['s3-port']),
119
164
  dataDir: args['data-dir'],
120
165
  });
121
166
  }
167
+ let bunnyServer = null;
168
+ if (args.bunny) {
169
+ const { startBunnyLocal } = await import('./bunny-local.js');
170
+ bunnyServer = await startBunnyLocal({
171
+ port: Number(args['bunny-port']),
172
+ dataDir: args['data-dir'],
173
+ });
174
+ }
122
175
  log.orez('ready');
123
176
  log.orez(`pg: postgresql://${config.pgUser}:${config.pgPassword}@127.0.0.1:${config.pgPort}/postgres`);
124
177
  if (!config.skipZeroCache) {
125
178
  log.zero(`http://localhost:${config.zeroPort}`);
126
179
  }
127
180
  process.on('SIGINT', async () => {
181
+ bunnyServer?.close();
128
182
  s3Server?.close();
129
183
  await stop();
130
184
  process.exit(0);
131
185
  });
132
186
  process.on('SIGTERM', async () => {
187
+ bunnyServer?.close();
133
188
  s3Server?.close();
134
189
  await stop();
135
190
  process.exit(0);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -6,8 +6,8 @@
6
6
  * `bun run` command.
7
7
  */
8
8
  import type { ZeroLiteConfig } from './config.js';
9
- export type { ZeroLiteConfig, LogLevel } from './config.js';
10
9
  export { getConfig, getConnectionString } from './config.js';
10
+ export type { LogLevel, ZeroLiteConfig } from './config.js';
11
11
  export declare function startZeroLite(overrides?: Partial<ZeroLiteConfig>): Promise<{
12
12
  config: ZeroLiteConfig;
13
13
  stop: () => Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAaH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAIjD,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAE5D,wBAAsB,aAAa,CAAC,SAAS,GAAE,OAAO,CAAC,cAAc,CAAM;;;GA4D1E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAaH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAGjD,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAC5D,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAE3D,wBAAsB,aAAa,CAAC,SAAS,GAAE,OAAO,CAAC,cAAc,CAAM;;;GA4D1E"}
package/dist/index.js CHANGED
@@ -6,8 +6,8 @@
6
6
  * `bun run` command.
7
7
  */
8
8
  import { spawn } from 'node:child_process';
9
- import { existsSync, readFileSync, mkdirSync, writeFileSync, unlinkSync } from 'node:fs';
10
- import { resolve, join } from 'node:path';
9
+ import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
10
+ import { resolve } from 'node:path';
11
11
  import { getConfig, getConnectionString } from './config.js';
12
12
  import { log } from './log.js';
13
13
  import { startPgProxy } from './pg-proxy.js';
@@ -124,6 +124,28 @@ async function seedIfNeeded(db, config) {
124
124
  }
125
125
  log.orez('seeded demo data');
126
126
  }
127
+ function patchSqliteForWasm() {
128
+ // replace @rocicorp/zero-sqlite3 with bedrock-sqlite (wasm) shim
129
+ // so zero-cache uses wasm instead of native bindings
130
+ try {
131
+ const sqlitePkg = import.meta.resolve('@rocicorp/zero-sqlite3').replace('file://', '');
132
+ const indexPath = resolve(sqlitePkg, '..', 'index.js');
133
+ if (!existsSync(indexPath))
134
+ return;
135
+ const current = readFileSync(indexPath, 'utf-8');
136
+ if (current.includes('bedrock-sqlite'))
137
+ return; // already patched
138
+ const shimPath = resolve(import.meta.dirname, 'sqlite-shim.cjs');
139
+ if (!existsSync(shimPath))
140
+ return;
141
+ const shim = `'use strict';\nmodule.exports = require('${shimPath}');\n`;
142
+ writeFileSync(indexPath, shim);
143
+ log.orez('patched @rocicorp/zero-sqlite3 -> bedrock-sqlite (wasm)');
144
+ }
145
+ catch (e) {
146
+ log.orez(`sqlite wasm patch skipped: ${e}`);
147
+ }
148
+ }
127
149
  async function startZeroCache(config) {
128
150
  // resolve @rocicorp/zero entry, cli.js is right next to it
129
151
  let zeroCacheBin = '';
@@ -139,6 +161,8 @@ async function startZeroCache(config) {
139
161
  if (!zeroCacheBin) {
140
162
  throw new Error('zero-cache binary not found. install @rocicorp/zero');
141
163
  }
164
+ // patch sqlite to use wasm before spawning zero-cache
165
+ patchSqliteForWasm();
142
166
  const upstreamUrl = getConnectionString(config, 'postgres');
143
167
  const cvrUrl = getConnectionString(config, 'zero_cvr');
144
168
  const cdbUrl = getConnectionString(config, 'zero_cdb');
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/log.d.ts CHANGED
@@ -4,5 +4,6 @@ export declare const log: {
4
4
  proxy: (...args: unknown[]) => void;
5
5
  zero: (...args: unknown[]) => void;
6
6
  s3: (...args: unknown[]) => void;
7
+ bunny: (...args: unknown[]) => void;
7
8
  };
8
9
  //# sourceMappingURL=log.d.ts.map
package/dist/log.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAuBA,eAAO,MAAM,GAAG;oBALG,OAAO,EAAE;sBAAT,OAAO,EAAE;qBAAT,OAAO,EAAE;oBAAT,OAAO,EAAE;kBAAT,OAAO,EAAE;CAW3B,CAAA"}
1
+ {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAuBA,eAAO,MAAM,GAAG;oBALG,OAAO,EAAE;sBAAT,OAAO,EAAE;qBAAT,OAAO,EAAE;oBAAT,OAAO,EAAE;kBAAT,OAAO,EAAE;qBAAT,OAAO,EAAE;CAY3B,CAAA"}
package/dist/log.js CHANGED
@@ -23,5 +23,6 @@ export const log = {
23
23
  proxy: makeLogger('pg-proxy', COLORS.yellow),
24
24
  zero: makeLogger('zero-cache', COLORS.magenta),
25
25
  s3: makeLogger('orez/s3', COLORS.blue),
26
+ bunny: makeLogger('orez/bunny', COLORS.cyan),
26
27
  };
27
28
  //# sourceMappingURL=log.js.map
package/dist/log.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"log.js","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA,MAAM,KAAK,GAAG,SAAS,CAAA;AACvB,MAAM,IAAI,GAAG,SAAS,CAAA;AACtB,MAAM,GAAG,GAAG,SAAS,CAAA;AAErB,MAAM,MAAM,GAAG;IACb,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,UAAU;IACjB,MAAM,EAAE,UAAU;IAClB,OAAO,EAAE,UAAU;IACnB,IAAI,EAAE,UAAU;CACR,CAAA;AAEV,SAAS,MAAM,CAAC,KAAa,EAAE,KAAa;IAC1C,OAAO,GAAG,IAAI,GAAG,KAAK,IAAI,KAAK,IAAI,KAAK,EAAE,CAAA;AAC5C,CAAC;AAED,SAAS,UAAU,CAAC,KAAa,EAAE,KAAa;IAC9C,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;IAC9B,OAAO,CAAC,GAAG,IAAe,EAAE,EAAE;QAC5B,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAA;IAC1B,CAAC,CAAA;AACH,CAAC;AAED,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,IAAI,EAAE,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC;IACrC,MAAM,EAAE,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC;IAC1C,KAAK,EAAE,UAAU,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC;IAC5C,IAAI,EAAE,UAAU,CAAC,YAAY,EAAE,MAAM,CAAC,OAAO,CAAC;IAC9C,EAAE,EAAE,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC;CACvC,CAAA"}
1
+ {"version":3,"file":"log.js","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA,MAAM,KAAK,GAAG,SAAS,CAAA;AACvB,MAAM,IAAI,GAAG,SAAS,CAAA;AACtB,MAAM,GAAG,GAAG,SAAS,CAAA;AAErB,MAAM,MAAM,GAAG;IACb,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,UAAU;IACjB,MAAM,EAAE,UAAU;IAClB,OAAO,EAAE,UAAU;IACnB,IAAI,EAAE,UAAU;CACR,CAAA;AAEV,SAAS,MAAM,CAAC,KAAa,EAAE,KAAa;IAC1C,OAAO,GAAG,IAAI,GAAG,KAAK,IAAI,KAAK,IAAI,KAAK,EAAE,CAAA;AAC5C,CAAC;AAED,SAAS,UAAU,CAAC,KAAa,EAAE,KAAa;IAC9C,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;IAC9B,OAAO,CAAC,GAAG,IAAe,EAAE,EAAE;QAC5B,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAA;IAC1B,CAAC,CAAA;AACH,CAAC;AAED,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,IAAI,EAAE,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC;IACrC,MAAM,EAAE,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC;IAC1C,KAAK,EAAE,UAAU,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC;IAC5C,IAAI,EAAE,UAAU,CAAC,YAAY,EAAE,MAAM,CAAC,OAAO,CAAC;IAC9C,EAAE,EAAE,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC;IACtC,KAAK,EAAE,UAAU,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC;CAC7C,CAAA"}
@@ -3,6 +3,8 @@ import type { Plugin } from 'vite';
3
3
  export interface OrezPluginOptions extends Partial<ZeroLiteConfig> {
4
4
  s3?: boolean;
5
5
  s3Port?: number;
6
+ bunny?: boolean;
7
+ bunnyPort?: number;
6
8
  }
7
9
  export default function orez(options?: OrezPluginOptions): Plugin;
8
10
  //# sourceMappingURL=vite-plugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"vite-plugin.d.ts","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAElC,MAAM,WAAW,iBAAkB,SAAQ,OAAO,CAAC,cAAc,CAAC;IAChE,EAAE,CAAC,EAAE,OAAO,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,MAAM,CA2BhE"}
1
+ {"version":3,"file":"vite-plugin.d.ts","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAElC,MAAM,WAAW,iBAAkB,SAAQ,OAAO,CAAC,cAAc,CAAC;IAChE,EAAE,CAAC,EAAE,OAAO,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAsChE"}
@@ -1,20 +1,29 @@
1
1
  import { startZeroLite } from './index.js';
2
- import { startS3Local } from './s3-local.js';
3
2
  export default function orez(options) {
4
3
  let stop = null;
5
4
  let s3Server = null;
5
+ let bunnyServer = null;
6
6
  return {
7
7
  name: 'orez',
8
8
  async configureServer(server) {
9
9
  const result = await startZeroLite(options);
10
10
  stop = result.stop;
11
11
  if (options?.s3) {
12
+ const { startS3Local } = await import('./s3-local.js');
12
13
  s3Server = await startS3Local({
13
14
  port: options.s3Port || 9200,
14
15
  dataDir: result.config.dataDir,
15
16
  });
16
17
  }
18
+ if (options?.bunny) {
19
+ const { startBunnyLocal } = await import('./bunny-local.js');
20
+ bunnyServer = await startBunnyLocal({
21
+ port: options.bunnyPort || 3533,
22
+ dataDir: result.config.dataDir,
23
+ });
24
+ }
17
25
  server.httpServer?.on('close', async () => {
26
+ bunnyServer?.close();
18
27
  s3Server?.close();
19
28
  if (stop) {
20
29
  await stop();
@@ -1 +1 @@
1
- {"version":3,"file":"vite-plugin.js","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAW5C,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,OAA2B;IACtD,IAAI,IAAI,GAAiC,IAAI,CAAA;IAC7C,IAAI,QAAQ,GAAkB,IAAI,CAAA;IAElC,OAAO;QACL,IAAI,EAAE,MAAM;QAEZ,KAAK,CAAC,eAAe,CAAC,MAAM;YAC1B,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,CAAA;YAC3C,IAAI,GAAG,MAAM,CAAC,IAAI,CAAA;YAElB,IAAI,OAAO,EAAE,EAAE,EAAE,CAAC;gBAChB,QAAQ,GAAG,MAAM,YAAY,CAAC;oBAC5B,IAAI,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI;oBAC5B,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO;iBAC/B,CAAC,CAAA;YACJ,CAAC;YAED,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;gBACxC,QAAQ,EAAE,KAAK,EAAE,CAAA;gBACjB,IAAI,IAAI,EAAE,CAAC;oBACT,MAAM,IAAI,EAAE,CAAA;oBACZ,IAAI,GAAG,IAAI,CAAA;gBACb,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;KACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"vite-plugin.js","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAa1C,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,OAA2B;IACtD,IAAI,IAAI,GAAiC,IAAI,CAAA;IAC7C,IAAI,QAAQ,GAAkB,IAAI,CAAA;IAClC,IAAI,WAAW,GAAkB,IAAI,CAAA;IAErC,OAAO;QACL,IAAI,EAAE,MAAM;QAEZ,KAAK,CAAC,eAAe,CAAC,MAAM;YAC1B,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,CAAA;YAC3C,IAAI,GAAG,MAAM,CAAC,IAAI,CAAA;YAElB,IAAI,OAAO,EAAE,EAAE,EAAE,CAAC;gBAChB,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;gBACtD,QAAQ,GAAG,MAAM,YAAY,CAAC;oBAC5B,IAAI,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI;oBAC5B,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO;iBAC/B,CAAC,CAAA;YACJ,CAAC;YAED,IAAI,OAAO,EAAE,KAAK,EAAE,CAAC;gBACnB,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAA;gBAC5D,WAAW,GAAG,MAAM,eAAe,CAAC;oBAClC,IAAI,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI;oBAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO;iBAC/B,CAAC,CAAA;YACJ,CAAC;YAED,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;gBACxC,WAAW,EAAE,KAAK,EAAE,CAAA;gBACpB,QAAQ,EAAE,KAAK,EAAE,CAAA;gBACjB,IAAI,IAAI,EAAE,CAAC;oBACT,MAAM,IAAI,EAAE,CAAA;oBACZ,IAAI,GAAG,IAAI,CAAA;gBACb,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;KACF,CAAA;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orez",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
4
4
  "description": "PGlite-powered zero-sync development backend. No Docker required.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -15,6 +15,10 @@
15
15
  "types": "./dist/s3-local.d.ts",
16
16
  "import": "./dist/s3-local.js"
17
17
  },
18
+ "./bunny": {
19
+ "types": "./dist/bunny-local.d.ts",
20
+ "import": "./dist/bunny-local.js"
21
+ },
18
22
  "./vite": {
19
23
  "types": "./dist/vite-plugin.d.ts",
20
24
  "import": "./dist/vite-plugin.js"
@@ -43,6 +47,7 @@
43
47
  "dependencies": {
44
48
  "@electric-sql/pglite": "^0.2.17",
45
49
  "@rocicorp/zero": ">=0.1.0",
50
+ "bedrock-sqlite": "0.0.2",
46
51
  "citty": "^0.2.0",
47
52
  "pg-gateway": "^0.3.0-beta.4"
48
53
  },
@@ -54,7 +59,7 @@
54
59
  "optional": true
55
60
  }
56
61
  },
57
- "devDependencies": {
62
+ "devDependencies": {
58
63
  "oxlint": "latest",
59
64
  "oxfmt": "latest",
60
65
  "typescript": "^5.7.0",
@@ -0,0 +1,224 @@
1
+ /**
2
+ * minimal local bunny cdn storage-compatible server.
3
+ * handles GET/PUT/DELETE/HEAD and directory listing.
4
+ */
5
+
6
+ import {
7
+ existsSync,
8
+ mkdirSync,
9
+ readFileSync,
10
+ writeFileSync,
11
+ unlinkSync,
12
+ statSync,
13
+ readdirSync,
14
+ } from 'node:fs'
15
+ import {
16
+ createServer,
17
+ type Server,
18
+ type IncomingMessage,
19
+ type ServerResponse,
20
+ } from 'node:http'
21
+ import { join, dirname, extname, relative } from 'node:path'
22
+
23
+ import { log } from './log.js'
24
+
25
+ export interface BunnyLocalConfig {
26
+ port: number
27
+ dataDir: string
28
+ }
29
+
30
+ const MIME_TYPES: Record<string, string> = {
31
+ '.jpg': 'image/jpeg',
32
+ '.jpeg': 'image/jpeg',
33
+ '.png': 'image/png',
34
+ '.gif': 'image/gif',
35
+ '.webp': 'image/webp',
36
+ '.svg': 'image/svg+xml',
37
+ '.json': 'application/json',
38
+ '.txt': 'text/plain',
39
+ '.pdf': 'application/pdf',
40
+ '.mp4': 'video/mp4',
41
+ '.mp3': 'audio/mpeg',
42
+ '.css': 'text/css',
43
+ '.js': 'application/javascript',
44
+ '.html': 'text/html',
45
+ '.woff': 'font/woff',
46
+ '.woff2': 'font/woff2',
47
+ '.ttf': 'font/ttf',
48
+ '.otf': 'font/otf',
49
+ }
50
+
51
+ function corsHeaders(): Record<string, string> {
52
+ return {
53
+ 'Access-Control-Allow-Origin': '*',
54
+ 'Access-Control-Allow-Methods': 'GET, PUT, DELETE, HEAD, OPTIONS',
55
+ 'Access-Control-Allow-Headers': '*',
56
+ 'Access-Control-Expose-Headers': 'Content-Length',
57
+ }
58
+ }
59
+
60
+ // recursively collect files for directory listing
61
+ function listFiles(
62
+ dir: string,
63
+ baseDir: string
64
+ ): Array<{
65
+ Guid: string
66
+ StorageZoneName: string
67
+ Path: string
68
+ ObjectName: string
69
+ Length: number
70
+ LastChanged: string
71
+ IsDirectory: boolean
72
+ DateCreated: string
73
+ }> {
74
+ if (!existsSync(dir) || !statSync(dir).isDirectory()) {
75
+ return []
76
+ }
77
+
78
+ const entries = readdirSync(dir, { withFileTypes: true })
79
+ return entries.map((entry) => {
80
+ const fullPath = join(dir, entry.name)
81
+ const stat = statSync(fullPath)
82
+ const relativePath = '/' + relative(baseDir, dir) + '/'
83
+
84
+ return {
85
+ Guid: '00000000-0000-0000-0000-000000000000',
86
+ StorageZoneName: '',
87
+ Path: relativePath,
88
+ ObjectName: entry.name,
89
+ Length: entry.isDirectory() ? 0 : stat.size,
90
+ LastChanged: stat.mtime.toISOString(),
91
+ IsDirectory: entry.isDirectory(),
92
+ DateCreated: stat.birthtime.toISOString(),
93
+ }
94
+ })
95
+ }
96
+
97
+ export function startBunnyLocal(config: BunnyLocalConfig): Promise<Server> {
98
+ const storageDir = join(config.dataDir, 'bunny')
99
+ mkdirSync(storageDir, { recursive: true })
100
+
101
+ const server = createServer((req: IncomingMessage, res: ServerResponse) => {
102
+ const headers = corsHeaders()
103
+
104
+ if (req.method === 'OPTIONS') {
105
+ res.writeHead(200, headers)
106
+ res.end()
107
+ return
108
+ }
109
+
110
+ const url = new URL(req.url || '/', `http://localhost:${config.port}`)
111
+
112
+ // sanitize path to prevent traversal
113
+ const normalized = url.pathname
114
+ .split('/')
115
+ .filter((s) => s && s !== '..' && s !== '.')
116
+ .join('/')
117
+ const filePath = join(storageDir, normalized)
118
+ if (!filePath.startsWith(storageDir)) {
119
+ res.writeHead(403, headers)
120
+ res.end()
121
+ return
122
+ }
123
+
124
+ try {
125
+ switch (req.method) {
126
+ case 'GET': {
127
+ // directory listing if path ends with / or is a directory
128
+ if (
129
+ url.pathname.endsWith('/') ||
130
+ (existsSync(filePath) && statSync(filePath).isDirectory())
131
+ ) {
132
+ const items = listFiles(filePath, storageDir)
133
+ const body = JSON.stringify(items)
134
+ res.writeHead(200, {
135
+ ...headers,
136
+ 'Content-Type': 'application/json',
137
+ })
138
+ res.end(body)
139
+ return
140
+ }
141
+
142
+ if (!existsSync(filePath)) {
143
+ res.writeHead(404, { ...headers, 'Content-Type': 'application/json' })
144
+ res.end(JSON.stringify({ HttpCode: 404, Message: 'Object Not Found' }))
145
+ return
146
+ }
147
+ const data = readFileSync(filePath)
148
+ const ext = extname(filePath)
149
+ const contentType = MIME_TYPES[ext] || 'application/octet-stream'
150
+ res.writeHead(200, {
151
+ ...headers,
152
+ 'Content-Type': contentType,
153
+ 'Content-Length': data.length.toString(),
154
+ })
155
+ res.end(data)
156
+ break
157
+ }
158
+
159
+ case 'PUT': {
160
+ const chunks: Buffer[] = []
161
+ req.on('data', (chunk: Buffer) => chunks.push(chunk))
162
+ req.on('end', () => {
163
+ mkdirSync(dirname(filePath), { recursive: true })
164
+ const body = Buffer.concat(chunks)
165
+ writeFileSync(filePath, body)
166
+ res.writeHead(201, {
167
+ ...headers,
168
+ 'Content-Type': 'application/json',
169
+ })
170
+ res.end(JSON.stringify({ HttpCode: 201, Message: 'File uploaded.' }))
171
+ })
172
+ break
173
+ }
174
+
175
+ case 'DELETE': {
176
+ if (existsSync(filePath)) {
177
+ unlinkSync(filePath)
178
+ }
179
+ res.writeHead(200, {
180
+ ...headers,
181
+ 'Content-Type': 'application/json',
182
+ })
183
+ res.end(JSON.stringify({ HttpCode: 200, Message: 'File deleted successfuly.' }))
184
+ break
185
+ }
186
+
187
+ case 'HEAD': {
188
+ if (!existsSync(filePath) || statSync(filePath).isDirectory()) {
189
+ res.writeHead(404, headers)
190
+ res.end()
191
+ return
192
+ }
193
+ const stat = statSync(filePath)
194
+ const ext2 = extname(filePath)
195
+ res.writeHead(200, {
196
+ ...headers,
197
+ 'Content-Type': MIME_TYPES[ext2] || 'application/octet-stream',
198
+ 'Content-Length': stat.size.toString(),
199
+ })
200
+ res.end()
201
+ break
202
+ }
203
+
204
+ default:
205
+ res.writeHead(405, headers)
206
+ res.end()
207
+ }
208
+ } catch {
209
+ res.writeHead(500, {
210
+ ...headers,
211
+ 'Content-Type': 'application/json',
212
+ })
213
+ res.end(JSON.stringify({ HttpCode: 500, Message: 'Internal Server Error' }))
214
+ }
215
+ })
216
+
217
+ return new Promise((resolve, reject) => {
218
+ server.listen(config.port, '127.0.0.1', () => {
219
+ log.bunny(`listening on port ${config.port}`)
220
+ resolve(server)
221
+ })
222
+ server.on('error', reject)
223
+ })
224
+ }
package/src/cli.ts CHANGED
@@ -3,7 +3,6 @@ import { defineCommand, runMain } from 'citty'
3
3
 
4
4
  import { startZeroLite } from './index.js'
5
5
  import { log } from './log.js'
6
- import { startS3Local } from './s3-local.js'
7
6
 
8
7
  const s3Command = defineCommand({
9
8
  meta: {
@@ -23,6 +22,7 @@ const s3Command = defineCommand({
23
22
  },
24
23
  },
25
24
  async run({ args }) {
25
+ const { startS3Local } = await import('./s3-local.js')
26
26
  const server = await startS3Local({
27
27
  port: Number(args.port),
28
28
  dataDir: args['data-dir'],
@@ -39,6 +39,41 @@ const s3Command = defineCommand({
39
39
  },
40
40
  })
41
41
 
42
+ const bunnyCommand = defineCommand({
43
+ meta: {
44
+ name: 'bunny',
45
+ description: 'start a local bunny cdn storage-compatible server',
46
+ },
47
+ args: {
48
+ port: {
49
+ type: 'string',
50
+ description: 'port to listen on',
51
+ default: '3533',
52
+ },
53
+ 'data-dir': {
54
+ type: 'string',
55
+ description: 'data directory for stored files',
56
+ default: '.orez',
57
+ },
58
+ },
59
+ async run({ args }) {
60
+ const { startBunnyLocal } = await import('./bunny-local.js')
61
+ const server = await startBunnyLocal({
62
+ port: Number(args.port),
63
+ dataDir: args['data-dir'],
64
+ })
65
+
66
+ process.on('SIGINT', () => {
67
+ server.close()
68
+ process.exit(0)
69
+ })
70
+ process.on('SIGTERM', () => {
71
+ server.close()
72
+ process.exit(0)
73
+ })
74
+ },
75
+ })
76
+
42
77
  const main = defineCommand({
43
78
  meta: {
44
79
  name: 'orez',
@@ -100,9 +135,20 @@ const main = defineCommand({
100
135
  description: 's3 server port',
101
136
  default: '9200',
102
137
  },
138
+ bunny: {
139
+ type: 'boolean',
140
+ description: 'also start a local bunny cdn storage-compatible server',
141
+ default: false,
142
+ },
143
+ 'bunny-port': {
144
+ type: 'string',
145
+ description: 'bunny storage server port',
146
+ default: '3533',
147
+ },
103
148
  },
104
149
  subCommands: {
105
150
  s3: s3Command,
151
+ bunny: bunnyCommand,
106
152
  },
107
153
  async run({ args }) {
108
154
  const { config, stop } = await startZeroLite({
@@ -119,12 +165,22 @@ const main = defineCommand({
119
165
 
120
166
  let s3Server: import('node:http').Server | null = null
121
167
  if (args.s3) {
168
+ const { startS3Local } = await import('./s3-local.js')
122
169
  s3Server = await startS3Local({
123
170
  port: Number(args['s3-port']),
124
171
  dataDir: args['data-dir'],
125
172
  })
126
173
  }
127
174
 
175
+ let bunnyServer: import('node:http').Server | null = null
176
+ if (args.bunny) {
177
+ const { startBunnyLocal } = await import('./bunny-local.js')
178
+ bunnyServer = await startBunnyLocal({
179
+ port: Number(args['bunny-port']),
180
+ dataDir: args['data-dir'],
181
+ })
182
+ }
183
+
128
184
  log.orez('ready')
129
185
  log.orez(
130
186
  `pg: postgresql://${config.pgUser}:${config.pgPassword}@127.0.0.1:${config.pgPort}/postgres`
@@ -134,11 +190,13 @@ const main = defineCommand({
134
190
  }
135
191
 
136
192
  process.on('SIGINT', async () => {
193
+ bunnyServer?.close()
137
194
  s3Server?.close()
138
195
  await stop()
139
196
  process.exit(0)
140
197
  })
141
198
  process.on('SIGTERM', async () => {
199
+ bunnyServer?.close()
142
200
  s3Server?.close()
143
201
  await stop()
144
202
  process.exit(0)
package/src/index.ts CHANGED
@@ -7,8 +7,8 @@
7
7
  */
8
8
 
9
9
  import { spawn, type ChildProcess } from 'node:child_process'
10
- import { existsSync, readFileSync, mkdirSync, writeFileSync, unlinkSync } from 'node:fs'
11
- import { resolve, join } from 'node:path'
10
+ import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs'
11
+ import { resolve } from 'node:path'
12
12
 
13
13
  import { getConfig, getConnectionString } from './config.js'
14
14
  import { log } from './log.js'
@@ -19,10 +19,9 @@ import { installChangeTracking } from './replication/change-tracker.js'
19
19
 
20
20
  import type { ZeroLiteConfig } from './config.js'
21
21
  import type { PGlite } from '@electric-sql/pglite'
22
- import type { Server } from 'node:net'
23
22
 
24
- export type { ZeroLiteConfig, LogLevel } from './config.js'
25
23
  export { getConfig, getConnectionString } from './config.js'
24
+ export type { LogLevel, ZeroLiteConfig } from './config.js'
26
25
 
27
26
  export async function startZeroLite(overrides: Partial<ZeroLiteConfig> = {}) {
28
27
  const config = getConfig(overrides)
@@ -152,6 +151,28 @@ async function seedIfNeeded(db: PGlite, config: ZeroLiteConfig): Promise<void> {
152
151
  log.orez('seeded demo data')
153
152
  }
154
153
 
154
+ function patchSqliteForWasm(): void {
155
+ // replace @rocicorp/zero-sqlite3 with bedrock-sqlite (wasm) shim
156
+ // so zero-cache uses wasm instead of native bindings
157
+ try {
158
+ const sqlitePkg = import.meta.resolve('@rocicorp/zero-sqlite3').replace('file://', '')
159
+ const indexPath = resolve(sqlitePkg, '..', 'index.js')
160
+ if (!existsSync(indexPath)) return
161
+
162
+ const current = readFileSync(indexPath, 'utf-8')
163
+ if (current.includes('bedrock-sqlite')) return // already patched
164
+
165
+ const shimPath = resolve(import.meta.dirname, 'sqlite-shim.cjs')
166
+ if (!existsSync(shimPath)) return
167
+
168
+ const shim = `'use strict';\nmodule.exports = require('${shimPath}');\n`
169
+ writeFileSync(indexPath, shim)
170
+ log.orez('patched @rocicorp/zero-sqlite3 -> bedrock-sqlite (wasm)')
171
+ } catch (e) {
172
+ log.orez(`sqlite wasm patch skipped: ${e}`)
173
+ }
174
+ }
175
+
155
176
  async function startZeroCache(config: ZeroLiteConfig): Promise<ChildProcess> {
156
177
  // resolve @rocicorp/zero entry, cli.js is right next to it
157
178
  let zeroCacheBin = ''
@@ -167,6 +188,9 @@ async function startZeroCache(config: ZeroLiteConfig): Promise<ChildProcess> {
167
188
  throw new Error('zero-cache binary not found. install @rocicorp/zero')
168
189
  }
169
190
 
191
+ // patch sqlite to use wasm before spawning zero-cache
192
+ patchSqliteForWasm()
193
+
170
194
  const upstreamUrl = getConnectionString(config, 'postgres')
171
195
  const cvrUrl = getConnectionString(config, 'zero_cvr')
172
196
  const cdbUrl = getConnectionString(config, 'zero_cdb')
package/src/log.ts CHANGED
@@ -27,4 +27,5 @@ export const log = {
27
27
  proxy: makeLogger('pg-proxy', COLORS.yellow),
28
28
  zero: makeLogger('zero-cache', COLORS.magenta),
29
29
  s3: makeLogger('orez/s3', COLORS.blue),
30
+ bunny: makeLogger('orez/bunny', COLORS.cyan),
30
31
  }
@@ -0,0 +1,67 @@
1
+ // shim that makes bedrock-sqlite (wasm) compatible with @rocicorp/zero-sqlite3 (native)
2
+ // patches missing methods that zero-cache expects
3
+ 'use strict'
4
+
5
+ const mod = require('bedrock-sqlite')
6
+ const Database = mod.Database
7
+ const SqliteError = mod.SqliteError
8
+
9
+ // patch Database.prototype with methods zero-cache uses but bedrock-sqlite doesn't have
10
+ if (!Database.prototype.unsafeMode) {
11
+ Database.prototype.unsafeMode = function () {
12
+ return this
13
+ }
14
+ }
15
+ if (!Database.prototype.defaultSafeIntegers) {
16
+ Database.prototype.defaultSafeIntegers = function () {
17
+ return this
18
+ }
19
+ }
20
+ if (!Database.prototype.serialize) {
21
+ Database.prototype.serialize = function () {
22
+ throw new Error('serialize() not supported in wasm build')
23
+ }
24
+ }
25
+ if (!Database.prototype.backup) {
26
+ Database.prototype.backup = function () {
27
+ throw new Error('backup() not supported in wasm build')
28
+ }
29
+ }
30
+
31
+ // patch Statement prototype - find it from a temp db instance
32
+ const tmpDb = new Database(':memory:')
33
+ const tmpStmt = tmpDb.prepare('SELECT 1')
34
+ const StmtProto = Object.getPrototypeOf(tmpStmt)
35
+
36
+ if (!StmtProto.safeIntegers) {
37
+ StmtProto.safeIntegers = function () {
38
+ return this
39
+ }
40
+ }
41
+ if (!StmtProto.scanStatusV2) {
42
+ // returns empty stats - zero-cache uses this for query performance tracking
43
+ StmtProto.scanStatusV2 = function () {
44
+ return []
45
+ }
46
+ }
47
+ if (!StmtProto.scanStatusReset) {
48
+ StmtProto.scanStatusReset = function () {}
49
+ }
50
+
51
+ tmpDb.close()
52
+
53
+ // scanstat constants (zero-cache references these as static properties)
54
+ Database.SQLITE_SCANSTAT_NLOOP = 0
55
+ Database.SQLITE_SCANSTAT_NVISIT = 1
56
+ Database.SQLITE_SCANSTAT_EST = 2
57
+ Database.SQLITE_SCANSTAT_NAME = 3
58
+ Database.SQLITE_SCANSTAT_EXPLAIN = 4
59
+ Database.SQLITE_SCANSTAT_SELECTID = 5
60
+ Database.SQLITE_SCANSTAT_PARENTID = 6
61
+ Database.SQLITE_SCANSTAT_NCYCLE = 7
62
+ Database.SQLITE_SCANSTAT_COMPLEX = 8
63
+
64
+ // export in the same shape as @rocicorp/zero-sqlite3:
65
+ // default export is the Database constructor, SqliteError is a named export
66
+ module.exports = Database
67
+ module.exports.SqliteError = SqliteError
@@ -1,5 +1,4 @@
1
1
  import { startZeroLite } from './index.js'
2
- import { startS3Local } from './s3-local.js'
3
2
 
4
3
  import type { ZeroLiteConfig } from './config.js'
5
4
  import type { Server } from 'node:http'
@@ -8,11 +7,14 @@ import type { Plugin } from 'vite'
8
7
  export interface OrezPluginOptions extends Partial<ZeroLiteConfig> {
9
8
  s3?: boolean
10
9
  s3Port?: number
10
+ bunny?: boolean
11
+ bunnyPort?: number
11
12
  }
12
13
 
13
14
  export default function orez(options?: OrezPluginOptions): Plugin {
14
15
  let stop: (() => Promise<void>) | null = null
15
16
  let s3Server: Server | null = null
17
+ let bunnyServer: Server | null = null
16
18
 
17
19
  return {
18
20
  name: 'orez',
@@ -22,13 +24,23 @@ export default function orez(options?: OrezPluginOptions): Plugin {
22
24
  stop = result.stop
23
25
 
24
26
  if (options?.s3) {
27
+ const { startS3Local } = await import('./s3-local.js')
25
28
  s3Server = await startS3Local({
26
29
  port: options.s3Port || 9200,
27
30
  dataDir: result.config.dataDir,
28
31
  })
29
32
  }
30
33
 
34
+ if (options?.bunny) {
35
+ const { startBunnyLocal } = await import('./bunny-local.js')
36
+ bunnyServer = await startBunnyLocal({
37
+ port: options.bunnyPort || 3533,
38
+ dataDir: result.config.dataDir,
39
+ })
40
+ }
41
+
31
42
  server.httpServer?.on('close', async () => {
43
+ bunnyServer?.close()
32
44
  s3Server?.close()
33
45
  if (stop) {
34
46
  await stop()