@boluo-ai/relay 0.1.0 → 0.1.2

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/dist/cli.js CHANGED
@@ -13,7 +13,7 @@ function mintUserId() {
13
13
  }
14
14
 
15
15
  // src/cli.ts
16
- import { existsSync, statSync, readFileSync } from "fs";
16
+ import { existsSync, statSync, readFileSync, realpathSync } from "fs";
17
17
  import { extname, join, normalize, resolve as resolvePath } from "path";
18
18
  import { fileURLToPath } from "url";
19
19
  import { Command } from "commander";
@@ -2012,8 +2012,10 @@ async function installShutdownHandlers(handle, stdout) {
2012
2012
  var isDirect = (() => {
2013
2013
  try {
2014
2014
  const entry = process.argv[1] ?? "";
2015
- const url = new URL(`file://${entry}`).href;
2016
- return import.meta.url === url;
2015
+ if (!entry) return false;
2016
+ const entryReal = realpathSync(entry);
2017
+ const importReal = realpathSync(fileURLToPath(import.meta.url));
2018
+ return entryReal === importReal;
2017
2019
  } catch {
2018
2020
  return false;
2019
2021
  }
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@boluo-ai/relay",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Boluo encrypted relay — WebSocket bridge between Boluo daemon and Boluo web UI, with bundled web SPA.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "main": "./dist/cli.js",
8
8
  "bin": {
9
- "boluo-relay": "./dist/cli.js"
9
+ "boluo-relay": "dist/cli.js"
10
10
  },
11
11
  "files": [
12
12
  "dist",
@@ -1,8 +1,24 @@
1
- // App-shell service worker. Caches static assets only; explicitly bypasses
2
- // the WebSocket relay endpoint and /api so live data is never served stale.
1
+ // App-shell service worker.
2
+ //
3
+ // Strategy split (this matters — old versions used cache-first for everything
4
+ // which permanently pinned users to whatever HTML they first saw and made
5
+ // redeployments invisible):
6
+ //
7
+ // /assets/* → cache-first (Vite emits fingerprinted filenames, so a
8
+ // new build produces a new URL; cached entries
9
+ // for old URLs become harmless garbage that
10
+ // activate() purges on next SW upgrade).
11
+ // /ws, /api/* → bypassed entirely (live data must never be cached).
12
+ // everything → network-first with cache fallback. New deploys take effect
13
+ // else on the next page load, not whenever the user manually
14
+ // unregisters the SW.
15
+ //
16
+ // On `SW_VERSION` change, activate() deletes every other cache key so users
17
+ // pick up the new shell deterministically. Bump it when you change this
18
+ // strategy.
3
19
 
4
- const SW_VERSION = 'boluo-v1';
5
- const APP_SHELL = ['/', '/index.html', '/manifest.json'];
20
+ const SW_VERSION = 'boluo-v2';
21
+ const APP_SHELL = ['/index.html', '/manifest.json'];
6
22
 
7
23
  self.addEventListener('install', (e) => {
8
24
  e.waitUntil(caches.open(SW_VERSION).then((c) => c.addAll(APP_SHELL)));
@@ -18,22 +34,40 @@ self.addEventListener('activate', (e) => {
18
34
  self.clients.claim();
19
35
  });
20
36
 
37
+ function cacheFirst(request) {
38
+ return caches.match(request).then((hit) =>
39
+ hit ||
40
+ fetch(request).then((net) => {
41
+ if (net.ok) {
42
+ const clone = net.clone();
43
+ caches.open(SW_VERSION).then((cache) => cache.put(request, clone));
44
+ }
45
+ return net;
46
+ }),
47
+ );
48
+ }
49
+
50
+ function networkFirst(request) {
51
+ return fetch(request)
52
+ .then((net) => {
53
+ if (net.ok) {
54
+ const clone = net.clone();
55
+ caches.open(SW_VERSION).then((cache) => cache.put(request, clone));
56
+ }
57
+ return net;
58
+ })
59
+ .catch(() =>
60
+ caches.match(request).then((hit) => hit || caches.match('/index.html')),
61
+ );
62
+ }
63
+
21
64
  self.addEventListener('fetch', (e) => {
22
- const u = new URL(e.request.url);
23
65
  if (e.request.method !== 'GET') return;
66
+ const u = new URL(e.request.url);
24
67
  if (u.pathname === '/ws' || u.pathname.startsWith('/api')) return;
25
- e.respondWith(
26
- caches.match(e.request).then((r) =>
27
- r ||
28
- fetch(e.request)
29
- .then((net) => {
30
- if (net.ok) {
31
- const c = net.clone();
32
- caches.open(SW_VERSION).then((cache) => cache.put(e.request, c));
33
- }
34
- return net;
35
- })
36
- .catch(() => caches.match('/index.html')),
37
- ),
38
- );
68
+ if (u.pathname.startsWith('/assets/')) {
69
+ e.respondWith(cacheFirst(e.request));
70
+ return;
71
+ }
72
+ e.respondWith(networkFirst(e.request));
39
73
  });