wasm_rails 0.1.0 → 0.1.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e88c3bdb062ebc82a44f218f48d8e93614dda54d89a584f873a0715dbd130f82
4
- data.tar.gz: 103d7130d41648dcee8e9a527ec02fe8aab8f7e281a7b52ef194c6a4c33b86b8
3
+ metadata.gz: 452890d1347c1fcd610840906a6c70b8344a536d6c7a23faf99d7dd49c95ff59
4
+ data.tar.gz: 6798e36e8e0f72c0f0f2c6fbb9c588c12daed396cd26267e0aca8d6bdccce776
5
5
  SHA512:
6
- metadata.gz: ddc70640c5a8b8dc0ec733b0f89b8b2cd507bdd27ab187336b8cea2169f9828d7aa243ba93494896a1f9660b30e1c68d331d306691dde73809523316a76a6896
7
- data.tar.gz: 678917372a8eb43a1dfde066ed849d5597f26607f5637275f244c1f162cab4282b19be6e08620f17112d6092402ecf1e5ab80e475b3b29fbb4fe8998a7cd38d0
6
+ metadata.gz: 54eea9f197e9b567a2fb68649e8a79eca2aac2fc0286e4440228c37005b63f386d8bbaa06b70a0b6087b9b3ce715bef3908211883250a8ddb19b5a3bf57c3595
7
+ data.tar.gz: 2e9af8ca7598afed43e30b0f6916f28a1f2ed9f357d7c7fdf2369ea001b1a104e80d89d81ce6255b0d69db823cf432183af0c54c0e5ad5534921c521c7998aa3
@@ -217,15 +217,19 @@ async function handleImport(req) {
217
217
 
218
218
  let vm = null;
219
219
 
220
+ function escPath(p) {
221
+ return p.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/#{/g, '\\#{');
222
+ }
223
+
220
224
  function buildMountScript(bundle) {
221
225
  const entries = Object.entries(bundle).map(([path, b64]) => {
222
226
  const escaped = b64.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
223
- return `require 'base64'; File.write("${path}", Base64.decode64("${escaped}"))`;
227
+ return `require 'base64'; File.write("${escPath(path)}", Base64.decode64("${escaped}"))`;
224
228
  }).join("\n");
225
229
 
226
230
  const dirs = [...new Set(
227
231
  Object.keys(bundle).map(p => p.split('/').slice(0, -1).join('/'))
228
- )].sort().map(d => `FileUtils.mkdir_p("${d}")`).join("\n");
232
+ )].sort().map(d => `FileUtils.mkdir_p("${escPath(d)}")`).join("\n");
229
233
 
230
234
  return `require 'fileutils'\n${dirs}\n${entries}`;
231
235
  }
@@ -253,6 +257,7 @@ async function initRails() {
253
257
  broadcast({ type: 'progress', step: 'Booting Rails…' });
254
258
  rubyVM.eval(`
255
259
  load '/wasm_setup.rb'
260
+ require 'base64'
256
261
 
257
262
  ENV['RAILS_ENV'] = 'production'
258
263
  ENV['SECRET_KEY_BASE'] = 'wasm-local-secret-not-used-for-encryption'
@@ -310,14 +315,28 @@ async function boot() {
310
315
  return bootPromise;
311
316
  }
312
317
 
318
+ // Lazy boot: Safari/iOS only — avoids the install event timeout.
319
+ // Chrome/Edge use install-time boot so the SW is ready before activate fires.
320
+ const LAZY_BOOT = typeof __LAZY_BOOT__ !== 'undefined' ? __LAZY_BOOT__ : false;
321
+
313
322
  self.addEventListener('install', (event) => {
314
323
  event.waitUntil(
315
- boot()
316
- .then(() => caches.open(CACHE_VERSION))
317
- .then(() => self.skipWaiting())
324
+ LAZY_BOOT
325
+ ? caches.open(CACHE_VERSION).then(() => self.skipWaiting())
326
+ : boot().then(() => caches.open(CACHE_VERSION)).then(() => self.skipWaiting())
318
327
  );
319
328
  });
320
329
 
330
+ self.addEventListener('message', (event) => {
331
+ if (event.data?.type === 'boot') {
332
+ if (vm) {
333
+ broadcast({ type: 'ready' });
334
+ } else {
335
+ boot();
336
+ }
337
+ }
338
+ });
339
+
321
340
  self.addEventListener('activate', (event) => {
322
341
  event.waitUntil((async () => {
323
342
  const allCaches = await caches.keys();
@@ -329,9 +348,8 @@ self.addEventListener('activate', (event) => {
329
348
  await self.clients.claim();
330
349
 
331
350
  if (isUpdate) {
332
- console.log(`[sw] Updated to ${BUILD_ID} — reloading all clients`);
333
- const clients = await self.clients.matchAll({ type: 'window' });
334
- await Promise.all(clients.map(c => c.navigate(c.url).catch(() => {})));
351
+ console.log(`[sw] Updated to ${BUILD_ID} — notifying clients`);
352
+ broadcast({ type: 'update' });
335
353
  }
336
354
  })());
337
355
  });
@@ -364,11 +382,19 @@ async function handleRequest(req) {
364
382
  );
365
383
  }
366
384
 
367
- const body = ['GET', 'HEAD'].includes(req.method) ? '' : await req.text();
368
385
  const url = new URL(req.url);
369
386
  const headers = {};
370
387
  req.headers.forEach((v, k) => { headers[k] = v; });
371
388
 
389
+ // Base64-encode the body to safely pass binary data and preserve newlines.
390
+ let bodyB64 = '';
391
+ let bodyByteLength = 0;
392
+ if (!['GET', 'HEAD'].includes(req.method)) {
393
+ const bytes = new Uint8Array(await req.arrayBuffer());
394
+ bodyByteLength = bytes.length;
395
+ bodyB64 = btoa(Array.from(bytes, b => String.fromCharCode(b)).join(''));
396
+ }
397
+
372
398
  const httpHeaders = Object.entries(headers)
373
399
  .filter(([k]) => !['host', 'content-type', 'content-length'].includes(k.toLowerCase()))
374
400
  .map(([k, v]) => ` 'HTTP_${k.toUpperCase().replace(/-/g, '_')}' => '${escRuby(v)}'`)
@@ -382,8 +408,8 @@ async function handleRequest(req) {
382
408
  'QUERY_STRING' => '${escRuby(url.search.slice(1))}',
383
409
  'HTTP_HOST' => '${escRuby(url.host)}',
384
410
  ${headers['content-type'] ? `'CONTENT_TYPE' => '${escRuby(headers['content-type'])}',` : ''}
385
- 'CONTENT_LENGTH' => '${escRuby(String(body.length))}',
386
- 'rack.input' => StringIO.new('${escRuby(body)}'),
411
+ 'CONTENT_LENGTH' => '${bodyByteLength}',
412
+ 'rack.input' => StringIO.new(Base64.decode64('${bodyB64}')),
387
413
  'rack.errors' => $stderr,
388
414
  'rack.url_scheme' => '${escRuby(url.protocol.slice(0, -1))}',
389
415
  'rack.multithread' => false,
@@ -1,3 +1,3 @@
1
1
  module WasmRails
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wasm_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emerson Argueta
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-05-14 00:00:00.000000000 Z
11
+ date: 2026-05-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties