bit-byte-bit 0.0.0-stage → 2.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.
Files changed (33) hide show
  1. package/README.md +24 -2
  2. package/assets/bg/blue.mp4 +0 -0
  3. package/assets/bg/green.mp4 +0 -0
  4. package/assets/bg/poster.jpg +0 -0
  5. package/assets/bg/teal.mp4 +0 -0
  6. package/assets/fonts/auge-bold.otf +0 -0
  7. package/assets/fonts/auge-regular.otf +0 -0
  8. package/assets/fonts/auge-semibold.otf +0 -0
  9. package/assets/fonts/inter-var.ttf +0 -0
  10. package/assets/fonts/jetbrains-mono-var.ttf +0 -0
  11. package/assets/fonts/pacifico.ttf +0 -0
  12. package/assets/fonts/space-grotesk-var.ttf +0 -0
  13. package/assets/logos/bit-byte-bit-backup.svg +48 -0
  14. package/assets/logos/bit-byte-bit.svg +19 -0
  15. package/assets/site/backup/Pacifico-Regular-95szj24p.ttf +0 -0
  16. package/assets/site/backup/auge-bold-vywa1g7b.otf +0 -0
  17. package/assets/site/backup/auge-regular-hz0spgka.otf +0 -0
  18. package/assets/site/backup/auge-semibold-td2xkdwf.otf +0 -0
  19. package/assets/site/backup/copium-meme.png +0 -0
  20. package/assets/site/backup/engine/controller.api.js +1344 -0
  21. package/assets/site/backup/engine/controller.inject.js +511 -0
  22. package/assets/site/backup/engine/controller.sw.js +418 -0
  23. package/assets/site/backup/engine/corridor.js +13215 -0
  24. package/assets/site/backup/engine/corridor.wasm +0 -0
  25. package/assets/site/backup/site-backup.css +1 -0
  26. package/assets/site/backup/site-backup.js +74 -0
  27. package/assets/site/backup/sw.js +224 -0
  28. package/assets/site/index.html +113 -0
  29. package/assets/site/site.css +226 -0
  30. package/assets/site/site.js +188 -0
  31. package/index.cjs +83 -0
  32. package/index.d.ts +14 -0
  33. package/package.json +29 -4
@@ -0,0 +1,418 @@
1
+ var $corridorController;
2
+ (() => {
3
+ var __webpack_modules__ = ({
4
+ "./packages/rpc/index.ts"(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
5
+ __webpack_require__.r(__webpack_exports__);
6
+ __webpack_require__.d(__webpack_exports__, {
7
+ RpcHelper: () => (RpcHelper)
8
+ });
9
+ class RpcHelper {
10
+ methods;
11
+ id;
12
+ sendRaw;
13
+ counter = 0;
14
+ promiseCallbacks = new Map();
15
+ constructor(methods, id, sendRaw){
16
+ this.methods = methods;
17
+ this.id = id;
18
+ this.sendRaw = sendRaw;
19
+ }
20
+ recieve(data) {
21
+ if (data === undefined || data === null || typeof data !== "object") return;
22
+ const dt = data[this.id];
23
+ if (dt === undefined || dt === null || typeof dt !== "object") return;
24
+ const type = dt.$type;
25
+ if (type === "response") {
26
+ const token = dt.$token;
27
+ const data = dt.$data;
28
+ const error = dt.$error;
29
+ const cb = this.promiseCallbacks.get(token);
30
+ if (!cb) return;
31
+ this.promiseCallbacks.delete(token);
32
+ if (error !== undefined) {
33
+ cb.reject(new Error(error));
34
+ } else {
35
+ cb.resolve(data);
36
+ }
37
+ } else if (type === "request") {
38
+ const method = dt.$method;
39
+ const args = dt.$args;
40
+ this.methods[method](args).then((r)=>{
41
+ this.sendRaw({
42
+ [this.id]: {
43
+ $type: "response",
44
+ $token: dt.$token,
45
+ $data: r?.[0]
46
+ }
47
+ }, r?.[1]);
48
+ }).catch((err)=>{
49
+ console.error(err);
50
+ this.sendRaw({
51
+ [this.id]: {
52
+ $type: "response",
53
+ $token: dt.$token,
54
+ $error: err?.toString() || "Unknown error"
55
+ }
56
+ }, []);
57
+ });
58
+ }
59
+ }
60
+ call(method, args, transfer = []) {
61
+ const token = this.counter++;
62
+ return new Promise((resolve, reject)=>{
63
+ this.promiseCallbacks.set(token, {
64
+ resolve,
65
+ reject
66
+ });
67
+ this.sendRaw({
68
+ [this.id]: {
69
+ $type: "request",
70
+ $method: method,
71
+ $args: args,
72
+ $token: token
73
+ }
74
+ }, transfer);
75
+ });
76
+ }
77
+ }
78
+
79
+
80
+ },
81
+
82
+ });
83
+ // The module cache
84
+ var __webpack_module_cache__ = {};
85
+
86
+ // The require function
87
+ function __webpack_require__(moduleId) {
88
+
89
+ // Check if module is in cache
90
+ var cachedModule = __webpack_module_cache__[moduleId];
91
+ if (cachedModule !== undefined) {
92
+ return cachedModule.exports;
93
+ }
94
+ // Create a new module (and put it into the cache)
95
+ var module = (__webpack_module_cache__[moduleId] = {
96
+ exports: {}
97
+ });
98
+ // Execute the module function
99
+ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
100
+
101
+ // Return the exports of the module
102
+ return module.exports;
103
+
104
+ }
105
+
106
+ // webpack/runtime/define_property_getters
107
+ (() => {
108
+ __webpack_require__.d = (exports, definition) => {
109
+ for(var key in definition) {
110
+ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
111
+ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
112
+ }
113
+ }
114
+ };
115
+ })();
116
+ // webpack/runtime/has_own_property
117
+ (() => {
118
+ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
119
+ })();
120
+ // webpack/runtime/make_namespace_object
121
+ (() => {
122
+ // define __esModule on exports
123
+ __webpack_require__.r = (exports) => {
124
+ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
125
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
126
+ }
127
+ Object.defineProperty(exports, '__esModule', { value: true });
128
+ };
129
+ })();
130
+ var __webpack_exports__ = {};
131
+ // This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
132
+ (() => {
133
+ __webpack_require__.r(__webpack_exports__);
134
+ __webpack_require__.d(__webpack_exports__, {
135
+ route: () => (route),
136
+ shouldRoute: () => (shouldRoute)
137
+ });
138
+ /* import */ var _mercuryworkshop_rpc__rspack_import_0 = __webpack_require__("./packages/rpc/index.ts");
139
+ /// <reference lib="WebWorker" />
140
+ /// <reference types="@types/serviceworker" />
141
+
142
+ function makeId() {
143
+ return Math.random().toString(36).substring(2, 10);
144
+ }
145
+ const cookieResolvers = {};
146
+ addEventListener("message", (e)=>{
147
+ if (!e.data) return;
148
+ if (typeof e.data != "object") return;
149
+ if (e.data.$sw$setCookieDone && typeof e.data.$sw$setCookieDone == "object") {
150
+ const done = e.data.$sw$setCookieDone;
151
+ const resolver = cookieResolvers[done.id];
152
+ if (resolver) {
153
+ resolver();
154
+ delete cookieResolvers[done.id];
155
+ }
156
+ }
157
+ if (e.data.$sw$initRemoteTransport && typeof e.data.$sw$initRemoteTransport == "object") {
158
+ const { port, prefix } = e.data.$sw$initRemoteTransport;
159
+ const relevantcontroller = tabs.find((tab)=>new URL(prefix).pathname.startsWith(tab.prefix));
160
+ if (!relevantcontroller) {
161
+ console.error("No relevant controller found for transport init");
162
+ return;
163
+ }
164
+ relevantcontroller.rpc.call("initRemoteTransport", port, [
165
+ port
166
+ ]);
167
+ }
168
+ });
169
+ class ControllerReference {
170
+ prefix;
171
+ id;
172
+ rpc;
173
+ constructor(prefix, id, port){
174
+ this.prefix = prefix;
175
+ this.id = id;
176
+ this.rpc = new _mercuryworkshop_rpc__rspack_import_0.RpcHelper({
177
+ sendSetCookie: async ({ cookies, options })=>{
178
+ const clients1 = await self.clients.matchAll();
179
+ const ids = [];
180
+ const promises = [];
181
+ // Navigation fetches (document/iframe) deliver cookies via the inject
182
+ // script's embedded cookieJar dump — the destination page doesn't have
183
+ // inject.ts loaded yet to ack, so awaiting would deadlock. Broadcast
184
+ // so any already-loaded clients can update their jars, but don't wait.
185
+ const isNavigation = options?.destination === "document" || options?.destination === "iframe";
186
+ for (const client of clients1){
187
+ const id = makeId();
188
+ ids.push(id);
189
+ client.postMessage({
190
+ $controller$setCookie: {
191
+ cookies,
192
+ options,
193
+ id
194
+ }
195
+ });
196
+ if (!isNavigation) {
197
+ promises.push(new Promise((resolve)=>{
198
+ // Resolve with the id so we know which client replied.
199
+ cookieResolvers[id] = ()=>resolve(id);
200
+ }));
201
+ }
202
+ }
203
+ // Wait for the first client to acknowledge the cookie sync.
204
+ // Using Promise.any (not Promise.all) so that extra SW clients created by
205
+ // window.open (e.g. test popup windows) don't cause timeouts — only the
206
+ // main controller client needs to respond.
207
+ if (promises.length > 0) {
208
+ let timeoutId;
209
+ let responded = false;
210
+ const timeoutPromise = new Promise((resolve)=>{
211
+ timeoutId = setTimeout(()=>{
212
+ if (!responded) {
213
+ const pending = ids.filter((id)=>cookieResolvers[id] !== undefined);
214
+ console.error("timed out waiting for set cookie response (deadlock?): " + `cookies=${cookies.length} clients=${clients1.length} ` + `pending=${pending.length}/${ids.length} ` + `clientUrls=${clients1.map((c)=>c.url).join(",")}`);
215
+ }
216
+ resolve();
217
+ }, 1000);
218
+ });
219
+ try {
220
+ await Promise.race([
221
+ timeoutPromise,
222
+ Promise.any(promises).then(()=>{
223
+ responded = true;
224
+ }).catch(()=>{})
225
+ ]);
226
+ } finally{
227
+ // Clear the timeout so it doesn't fire spuriously after the
228
+ // race has already been won by Promise.any.
229
+ if (timeoutId !== undefined) clearTimeout(timeoutId);
230
+ // Clean up any pending resolvers so clients that never
231
+ // responded don't leak entries in cookieResolvers.
232
+ for (const id of ids){
233
+ delete cookieResolvers[id];
234
+ }
235
+ }
236
+ }
237
+ }
238
+ }, "tabchannel-" + id, (data, transfer)=>{
239
+ port.postMessage(data, transfer);
240
+ });
241
+ port.onmessage = (e)=>{
242
+ this.rpc.recieve(e.data);
243
+ };
244
+ port.onmessageerror = console.error;
245
+ this.rpc.call("ready", undefined);
246
+ }
247
+ }
248
+ const tabs = [];
249
+ // --- self-heal: tolerate SW restarts mid-session ---------------------------------
250
+ // The SW can be killed while idle (browser reclamation, SW update) and woken by a
251
+ // proxied fetch. tabs[] is rebuilt only when clients re-send $controller$init, so
252
+ // a fetch racing (or losing) that wake-up would 404 against the static server.
253
+ // When a /~/sj/ request matches no tab, we ping every client to re-register.
254
+ function tabForPathname(pathname) {
255
+ return tabs.find((tab)=>pathname.startsWith(tab.prefix));
256
+ }
257
+ let lastRevivePing = 0;
258
+ function requestRevive() {
259
+ const now = Date.now();
260
+ if (now - lastRevivePing < 500) return; // debounce: all subresources of one page
261
+ lastRevivePing = now;
262
+ console.warn("[corridor] proxied fetch with no registered tab — requesting re-init");
263
+ clients.matchAll().then((all)=>{
264
+ for (const client of all) client.postMessage({
265
+ $controller$swrevive: {}
266
+ });
267
+ });
268
+ }
269
+ // ---------------------------------------------------------------------------------
270
+ addEventListener("message", (e)=>{
271
+ if (!e.data) return;
272
+ if (typeof e.data != "object") return;
273
+ if (!e.data.$controller$init) return;
274
+ if (typeof e.data.$controller$init != "object") return;
275
+ const init = e.data.$controller$init;
276
+
277
+ const existing = tabs.findIndex((t)=>t.id === init.id);
278
+ if (existing !== -1) {
279
+ tabs.splice(existing, 1);
280
+ }
281
+ tabs.push(new ControllerReference(init.prefix, init.id, e.ports[0]));
282
+ });
283
+ function shouldRoute(event) {
284
+ const url = new URL(event.request.url);
285
+ const tab = tabForPathname(url.pathname);
286
+ // Under the SW's own scope, so builds served from a subfolder heal too.
287
+ if (!tab && url.pathname.startsWith(new URL(self.registration.scope).pathname + "~/sj/")) {
288
+ // Tab registry is empty/stale (SW restart race): wake the client so it
289
+ // re-sends $controller$init. This fetch itself may still 404 — the next
290
+ // attempt succeeds, and self-repairing loads recover automatically.
291
+ requestRevive();
292
+ }
293
+ return tab !== undefined;
294
+ }
295
+ // Error page shown in place of a page that failed to load through the
296
+ // proxy — connection/SSL/DNS failures (which throw) and failed top-level
297
+ // navigations (404 / 5xx responses). Subresource failures never see this:
298
+ // a missing image or script must not replace the whole page.
299
+ function isTopNavigation(event) {
300
+ // "iframe" is the important one here: proxied pages live in iframes, so
301
+ // their navigations arrive with destination "iframe", not "document".
302
+ return event.request.mode === "navigate"
303
+ || event.request.destination === "document"
304
+ || event.request.destination === "iframe";
305
+ }
306
+ function errorPage(detail) {
307
+ const safe = String(detail ?? "unknown error")
308
+ .replace(/[<>&"]/g, (c) => ({
309
+ "<": "&lt;",
310
+ ">": "&gt;",
311
+ "&": "&amp;",
312
+ '"': "&quot;"
313
+ }[c]));
314
+ const html = `<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Failed to load — copium</title><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap" rel="stylesheet"><style>html,body{margin:0;height:100%;background:transparent;font-family:Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif}body{display:flex;align-items:center;justify-content:center}.wrap{text-align:center;padding:24px;max-width:560px}h1{font-family:Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;color:#fff;font-size:28px;font-weight:700;margin:0 0 10px}p{font-family:Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;color:rgba(255,255,255,.55);font-size:14px;line-height:1.6;margin:0 0 18px}code{display:inline-block;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12.5px;color:rgba(255,255,255,.75);background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.1);border-radius:8px;padding:8px 12px;max-width:100%;word-break:break-all;text-align:left}</style></head><body><div class="wrap"><h1>Uh oh!</h1><p>Something failed, and copium failed to load the page. Try refreshing.</p><code>${safe}</code></div></body></html>`;
315
+ return new Response(html, {
316
+ status: 200,
317
+ headers: {
318
+ "content-type": "text/html; charset=utf-8",
319
+ "cache-control": "no-store"
320
+ }
321
+ });
322
+ }
323
+ // Wait briefly for a tab to (re)register after a revive ping — this covers the
324
+ // SW-restart race where the waking fetch arrives before the client's
325
+ // $controller$init handshake lands. Returns the tab or null.
326
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
327
+ async function tabAwaiting(pathname, timeoutMs = 2500) {
328
+ let tab = tabForPathname(pathname);
329
+ if (tab) return tab;
330
+ requestRevive();
331
+ const deadline = Date.now() + timeoutMs;
332
+ while (Date.now() < deadline) {
333
+ await sleep(100);
334
+ tab = tabForPathname(pathname);
335
+ if (tab) return tab;
336
+ }
337
+ return null;
338
+ }
339
+ async function route(event) {
340
+ try {
341
+ const url = new URL(event.request.url);
342
+ let tab = tabForPathname(url.pathname);
343
+ if (!tab) {
344
+ // No registered tab for this prefix — likely a freshly restarted SW.
345
+ // Give the client a moment to re-handshake before giving up.
346
+ tab = await tabAwaiting(url.pathname);
347
+ if (!tab) {
348
+ throw new Error("no proxy session for this tab (stale or restarted service worker)");
349
+ }
350
+ }
351
+ const client = await clients.get(event.clientId);
352
+ const rawheaders = [
353
+ ...event.request.headers
354
+ ];
355
+ const response = await tab.rpc.call("request", {
356
+ rawUrl: event.request.url,
357
+ rawReferrer: event.request.referrer,
358
+ destination: event.request.destination,
359
+ mode: event.request.mode,
360
+ referrer: event.request.referrer,
361
+ method: event.request.method,
362
+ body: event.request.body,
363
+ cache: event.request.cache,
364
+ forceCrossOriginIsolated: false,
365
+ initialHeaders: rawheaders,
366
+ rawClientUrl: client ? client.url : undefined,
367
+ clientId: event.clientId || event.resultingClientId
368
+ }, event.request.body instanceof ReadableStream || // @ts-expect-error the types for fetchevent are messed up
369
+ event.request.body instanceof ArrayBuffer ? [
370
+ event.request.body
371
+ ] : undefined);
372
+ // Failed page loads (404 / 5xx / transport-reported status 0) swap in
373
+ // the error page; the real response is untouched otherwise.
374
+ if (isTopNavigation(event) && (response.status === 0 || response.status === 404 || response.status >= 500)) {
375
+ console.warn("Page failed to load:", response.status, response.statusText);
376
+ return errorPage(`${response.status}${response.statusText ? " " + response.statusText : ""}`);
377
+ }
378
+ return new Response(response.body, {
379
+ status: response.status,
380
+ statusText: response.statusText,
381
+ headers: response.headers
382
+ });
383
+ } catch (e) {
384
+ console.error("Service Worker error:", e);
385
+ // Connection/SSL/DNS failures land here — render the error page for
386
+ // top-level navigations, keep the bare error for subresources.
387
+ if (isTopNavigation(event)) {
388
+ return errorPage(e.message || String(e));
389
+ }
390
+ return new Response("Internal Service Worker Error: " + e.message, {
391
+ status: 500
392
+ });
393
+ }
394
+ }
395
+ addEventListener("install", ()=>{
396
+ self.skipWaiting();
397
+ });
398
+ addEventListener("activate", (event)=>{
399
+ event.waitUntil(clients.claim());
400
+ });
401
+ // the only way to know if a service worker has suddenly died is if this code runs again
402
+ // notify all clients to send over their messageports again
403
+ setTimeout(async ()=>{
404
+ console.log("service worker activated, notifying clients to revive");
405
+ for (const client of (await clients.matchAll())){
406
+ client.postMessage({
407
+ $controller$swrevive: {}
408
+ });
409
+ }
410
+ // short delay is apparently needed
411
+ }, 100);
412
+
413
+ })();
414
+
415
+ $corridorController = __webpack_exports__;
416
+ })()
417
+ ;
418
+ //# sourceMappingURL=controller.sw.js.map