cursedbelt-core 2.1.0 → 2.2.0
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/core/activity/index.d.ts +2 -2
- package/dist/core/activity/index.js +1 -1
- package/dist/core/activity/model.d.ts +2 -2
- package/dist/core/analytics/index.d.ts +2 -2
- package/dist/core/analytics/index.js +2 -2
- package/dist/core/category/index.d.ts +3 -3
- package/dist/core/category/index.js +2 -2
- package/dist/core/category/memoryStore.d.ts +1 -1
- package/dist/core/category/memoryStore.js +1 -1
- package/dist/core/category/tree.d.ts +1 -1
- package/dist/core/colorScheme/index.d.ts +1 -1
- package/dist/core/colorScheme/index.js +1 -1
- package/dist/core/folder-tree/actions.d.ts +1 -1
- package/dist/core/folder-tree/actions.js +1 -1
- package/dist/core/folder-tree/index.d.ts +3 -3
- package/dist/core/folder-tree/index.js +3 -3
- package/dist/core/folder-tree/tree.js +1 -1
- package/dist/core/master-lock/index.d.ts +4 -4
- package/dist/core/master-lock/index.js +4 -4
- package/dist/core/master-lock/wire.d.ts +1 -1
- package/dist/core/media/ffmpeg.d.ts +1 -1
- package/dist/core/media/format.d.ts +1 -1
- package/dist/core/media/index.d.ts +12 -12
- package/dist/core/media/index.js +11 -11
- package/dist/core/media/mediaItem.d.ts +1 -1
- package/dist/core/media/renderPlan.d.ts +1 -1
- package/dist/core/media/renderPlan.js +1 -1
- package/dist/core/media/validate.d.ts +1 -1
- package/dist/core/media/validate.js +1 -1
- package/dist/core/navigation/coverageTest.d.ts +1 -1
- package/dist/core/navigation/coverageTest.js +1 -1
- package/dist/core/navigation/index.d.ts +6 -6
- package/dist/core/navigation/index.js +6 -6
- package/dist/core/navigation/migrateNavPreferences.d.ts +1 -1
- package/dist/core/navigation/navigationSelectors.d.ts +1 -1
- package/dist/core/navigation/navigationSelectors.js +1 -1
- package/dist/core/navigation/searchCatalogue.d.ts +1 -1
- package/dist/core/offline/shellWorker.d.ts +185 -0
- package/dist/core/offline/shellWorker.js +200 -0
- package/dist/core/palette/fuzzyRank.d.ts +1 -1
- package/dist/core/palette/index.d.ts +3 -3
- package/dist/core/palette/index.js +3 -3
- package/dist/core/sharing/index.d.ts +2 -2
- package/dist/core/sharing/index.js +1 -1
- package/dist/core/tokens/registry.d.ts +2 -2
- package/dist/core/tokens/registry.js +1 -1
- package/dist/core/uiScale/index.d.ts +2 -2
- package/dist/core/uiScale/index.js +2 -2
- package/dist/core/uiScale/uiScaleStore.js +1 -1
- package/dist/core/wire/__fixtures__/rowsMarshalWorker.js +1 -1
- package/dist/core/wire/index.d.ts +4 -4
- package/dist/core/wire/index.js +4 -4
- package/dist/core/wire/ingress.d.ts +1 -1
- package/dist/core/wire/ingress.js +3 -3
- package/dist/core/wire/marshalWorker.d.ts +1 -1
- package/dist/core/wire/marshalWorker.js +2 -2
- package/dist/core/wire/marshalling.js +1 -1
- package/dist/ctgr/chunkAccumulator.d.ts +1 -1
- package/dist/ctgr/chunkAccumulator.js +2 -2
- package/dist/ctgr/chunkStore.d.ts +1 -1
- package/dist/ctgr/chunkStore.js +2 -2
- package/dist/ctgr/codec.d.ts +1 -1
- package/dist/ctgr/codec.js +5 -5
- package/dist/ctgr/index.d.ts +9 -9
- package/dist/ctgr/index.js +9 -9
- package/dist/ctgr/v0compat.d.ts +1 -1
- package/dist/ctgr/v0compat.js +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/testing/index.d.ts +3 -3
- package/dist/testing/index.js +3 -3
- package/package.json +8 -2
- package/src/config/appConfig.spec.ts +1 -1
- package/src/core/activity/index.ts +2 -2
- package/src/core/activity/model.ts +2 -2
- package/src/core/analytics/index.ts +2 -2
- package/src/core/analytics/range.spec.ts +1 -1
- package/src/core/analytics/schedule.spec.ts +1 -1
- package/src/core/category/category.spec.ts +1 -1
- package/src/core/category/index.ts +3 -3
- package/src/core/category/memoryStore.ts +2 -2
- package/src/core/category/tree.ts +1 -1
- package/src/core/color.spec.ts +1 -1
- package/src/core/colorScheme/colorScheme.spec.ts +1 -1
- package/src/core/colorScheme/index.ts +1 -1
- package/src/core/download.spec.ts +1 -1
- package/src/core/duplicates/index.spec.ts +1 -1
- package/src/core/events/ccEventBus.spec.ts +1 -1
- package/src/core/file-tree/fileTreeModel.spec.ts +1 -1
- package/src/core/folder-tree/actions.spec.ts +2 -2
- package/src/core/folder-tree/actions.ts +2 -2
- package/src/core/folder-tree/index.ts +3 -3
- package/src/core/folder-tree/path.spec.ts +1 -1
- package/src/core/folder-tree/tree.spec.ts +1 -1
- package/src/core/folder-tree/tree.ts +1 -1
- package/src/core/master-lock/index.ts +4 -4
- package/src/core/master-lock/kdf.spec.ts +2 -2
- package/src/core/master-lock/presence.spec.ts +1 -1
- package/src/core/master-lock/wire.spec.ts +1 -1
- package/src/core/master-lock/wire.ts +1 -1
- package/src/core/media/bgRemoval.spec.ts +1 -1
- package/src/core/media/ffmpeg.spec.ts +2 -2
- package/src/core/media/ffmpeg.ts +1 -1
- package/src/core/media/format.spec.ts +1 -1
- package/src/core/media/format.ts +1 -1
- package/src/core/media/index.ts +12 -12
- package/src/core/media/mediaItem.spec.ts +2 -2
- package/src/core/media/mediaItem.ts +1 -1
- package/src/core/media/renderPlan.spec.ts +1 -1
- package/src/core/media/renderPlan.ts +2 -2
- package/src/core/media/segment.spec.ts +1 -1
- package/src/core/media/size.spec.ts +1 -1
- package/src/core/media/trim.spec.ts +1 -1
- package/src/core/media/validate.spec.ts +2 -2
- package/src/core/media/validate.ts +2 -2
- package/src/core/media/videoCuts.spec.ts +1 -1
- package/src/core/navigation/coverageTest.ts +2 -2
- package/src/core/navigation/index.ts +6 -6
- package/src/core/navigation/migrateNavPreferences.ts +1 -1
- package/src/core/navigation/navigation.spec.ts +1 -1
- package/src/core/navigation/navigationSelectors.ts +1 -1
- package/src/core/navigation/searchCatalogue.ts +1 -1
- package/src/core/net/reconnectSchedule.spec.ts +1 -1
- package/src/core/offline/shellWorker.spec.ts +392 -0
- package/src/core/offline/shellWorker.ts +346 -0
- package/src/core/offline/shellWorker.webworker.spec.ts +80 -0
- package/src/core/palette/fuzzyRank.ts +1 -1
- package/src/core/palette/index.ts +3 -3
- package/src/core/palette/palette.spec.ts +4 -4
- package/src/core/schema/projection.spec.ts +1 -1
- package/src/core/sharing/index.ts +2 -2
- package/src/core/sharing/model.spec.ts +1 -1
- package/src/core/tokens/registry.spec.ts +1 -1
- package/src/core/tokens/registry.ts +2 -2
- package/src/core/uiScale/index.ts +2 -2
- package/src/core/uiScale/uiScale.spec.ts +1 -1
- package/src/core/uiScale/uiScaleStore.ts +1 -1
- package/src/core/wire/__fixtures__/rowsMarshalWorker.ts +1 -1
- package/src/core/wire/index.ts +4 -4
- package/src/core/wire/ingress.spec.ts +2 -2
- package/src/core/wire/ingress.ts +3 -3
- package/src/core/wire/marshalWorker.spec.ts +2 -2
- package/src/core/wire/marshalWorker.ts +2 -2
- package/src/core/wire/marshalling.spec.ts +1 -1
- package/src/core/wire/marshalling.ts +1 -1
- package/src/core/wire/wireHub.spec.ts +1 -1
- package/src/ctgr/chunkAccumulator.ts +3 -3
- package/src/ctgr/chunkStore.spec.ts +2 -2
- package/src/ctgr/chunkStore.ts +3 -3
- package/src/ctgr/codec.spec.ts +4 -4
- package/src/ctgr/codec.ts +5 -5
- package/src/ctgr/index.ts +9 -9
- package/src/ctgr/v0compat.spec.ts +2 -2
- package/src/ctgr/v0compat.ts +3 -3
- package/src/index.ts +2 -2
- package/src/leafSubpathsImportNothing.spec.ts +5 -0
- package/src/testTmpRoot.spec.ts +1 -1
- package/src/testing/index.ts +3 -3
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The app-shell service worker, once, for every app that serves its shell offline
|
|
3
|
+
* (task 2073, 2026-09-22).
|
|
4
|
+
*
|
|
5
|
+
* `apps/roms` wrote this by hand as plain JS in `public/sw.js`, with a TypeScript
|
|
6
|
+
* twin in `src/offline/swRouting.ts` held in step by a comment saying "keep the two
|
|
7
|
+
* in step". `apps/music` needed the same worker, and a third hand copy is how a fix
|
|
8
|
+
* lands in one app and not the others. This module is the one body; an app's
|
|
9
|
+
* `src/sw.ts` passes a config and adds whatever is genuinely its own (background
|
|
10
|
+
* sync, an outbox, a digest-keyed media cache) as further listeners beside it.
|
|
11
|
+
*
|
|
12
|
+
* What it does, and it is deliberately all it does:
|
|
13
|
+
* - `install` — precache the shell and the config's `precache` list, then `skipWaiting`.
|
|
14
|
+
* - `activate` — delete every cache named `<cachePrefix>*` that is not this version's,
|
|
15
|
+
* then `clients.claim()`.
|
|
16
|
+
* - `fetch` — same-origin static ASSETS cache-first; document NAVIGATIONS
|
|
17
|
+
* network-first, falling back offline to the exact URL, then the same
|
|
18
|
+
* path ignoring the query, then the shell. Everything else is left on
|
|
19
|
+
* the network: `respondWith` is never called for it.
|
|
20
|
+
*
|
|
21
|
+
* 🔴 `/api/` is NEVER cached and NEVER served from a cache. It is auth-gated, and a
|
|
22
|
+
* browser whose session has since been revoked must not read yesterday's copy of a
|
|
23
|
+
* private response out of its own cache. That is not a default a config can switch
|
|
24
|
+
* off: `apiPrefixes` ADDS prefixes to `/api/`, it cannot remove it, a precache entry
|
|
25
|
+
* under an API prefix is refused when the worker is installed, and `shouldCache`
|
|
26
|
+
* refuses to store an `api` route even if a caller asks.
|
|
27
|
+
*
|
|
28
|
+
* 🔴 `noShellFallback` exists because of the 2026-08-12 frame incident in roms. A game
|
|
29
|
+
* boots by loading `/emulator-frame.html` into a sandboxed iframe — a NAVIGATION, so it
|
|
30
|
+
* went network-first, and offline with nothing cached under that path the fallback
|
|
31
|
+
* handed it the APP SHELL. The iframe rendered a second copy of the library where the
|
|
32
|
+
* game should be: no canvas, no error, no clue. Any document that is not the shell (an
|
|
33
|
+
* iframe, a popup, a print view) must be listed there, and must be in `precache` if it
|
|
34
|
+
* is meant to work offline at all — an offline miss on it then REJECTS, which is the
|
|
35
|
+
* honest answer, rather than resolving the wrong document.
|
|
36
|
+
*
|
|
37
|
+
* Imports nothing at runtime (`leafSubpathsImportNothing.spec.ts` holds it to that):
|
|
38
|
+
* it is bundled into a service worker, where every byte ships on every install.
|
|
39
|
+
* `scope` is typed structurally so this compiles without the WebWorker lib, is testable
|
|
40
|
+
* with a fake, and still accepts the real `self` — `shellWorker.webworker.spec.ts`
|
|
41
|
+
* typechecks exactly that against `lib.webworker.d.ts`.
|
|
42
|
+
*/
|
|
43
|
+
/** roms' `ASSET_EXT`, verbatim. */
|
|
44
|
+
export const DEFAULT_ASSET_EXT = /\.(?:js|mjs|css|wasm|woff2?|ttf|png|jpe?g|webp|svg|ico|json)$/i;
|
|
45
|
+
/** Always an API prefix, whatever the config says. */
|
|
46
|
+
export const ALWAYS_API_PREFIX = '/api/';
|
|
47
|
+
const apiPrefixesOf = (config) => {
|
|
48
|
+
const extra = config.apiPrefixes ?? [];
|
|
49
|
+
return extra.includes(ALWAYS_API_PREFIX) ? extra : [ALWAYS_API_PREFIX, ...extra];
|
|
50
|
+
};
|
|
51
|
+
const startsWithAny = (pathname, prefixes) => prefixes.some((prefix) => pathname.startsWith(prefix));
|
|
52
|
+
/**
|
|
53
|
+
* Classify a request. Order matters and is roms' order: non-GET and cross-origin
|
|
54
|
+
* first, then the API (so an API path that happens to end in `.json` is still `api`),
|
|
55
|
+
* then the app's own passthrough prefixes, then navigation, then assets.
|
|
56
|
+
*/
|
|
57
|
+
export function classifyRequest(facts, config = {}) {
|
|
58
|
+
if (facts.method !== 'GET')
|
|
59
|
+
return 'passthrough';
|
|
60
|
+
if (!facts.sameOrigin)
|
|
61
|
+
return 'passthrough';
|
|
62
|
+
if (startsWithAny(facts.pathname, apiPrefixesOf(config)))
|
|
63
|
+
return 'api';
|
|
64
|
+
if (startsWithAny(facts.pathname, config.passthroughPrefixes ?? []))
|
|
65
|
+
return 'passthrough';
|
|
66
|
+
if (facts.isNavigate)
|
|
67
|
+
return 'navigate';
|
|
68
|
+
if ((config.assetExtensions ?? DEFAULT_ASSET_EXT).test(facts.pathname))
|
|
69
|
+
return 'asset';
|
|
70
|
+
return 'passthrough';
|
|
71
|
+
}
|
|
72
|
+
/** Whether a response on this route may be written to the cache. Never `api`. */
|
|
73
|
+
export function shouldCache(route) {
|
|
74
|
+
return route === 'asset' || route === 'navigate';
|
|
75
|
+
}
|
|
76
|
+
/** May an offline miss on this navigation be answered with the shell? */
|
|
77
|
+
export function mayFallBackToShell(pathname, config = {}) {
|
|
78
|
+
return !(config.noShellFallback ?? []).includes(pathname);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Apply defaults and refuse the configs that would break a promise in the header.
|
|
82
|
+
* `installShellWorker` calls this; it is exported so an app's own test can prove its
|
|
83
|
+
* config is accepted without standing up a worker.
|
|
84
|
+
*/
|
|
85
|
+
export function resolveShellWorkerConfig(config) {
|
|
86
|
+
if (config.cachePrefix.trim() === '') {
|
|
87
|
+
// An empty prefix makes EVERY cache on the origin "an old version of ours", and
|
|
88
|
+
// activate would delete the app's other caches with it.
|
|
89
|
+
throw new Error('shell worker: cachePrefix must not be empty — activate deletes every cache it prefixes');
|
|
90
|
+
}
|
|
91
|
+
if (config.version.trim() === '')
|
|
92
|
+
throw new Error('shell worker: version must not be empty');
|
|
93
|
+
const shellPath = config.shellPath ?? '/';
|
|
94
|
+
const apiPrefixes = apiPrefixesOf(config);
|
|
95
|
+
const precache = config.precache.includes(shellPath) ? [...config.precache] : [shellPath, ...config.precache];
|
|
96
|
+
for (const path of precache) {
|
|
97
|
+
if (!path.startsWith('/')) {
|
|
98
|
+
throw new Error(`shell worker: precache entry "${path}" must be a same-origin path starting with "/"`);
|
|
99
|
+
}
|
|
100
|
+
if (startsWithAny(path, apiPrefixes)) {
|
|
101
|
+
throw new Error(`shell worker: precache entry "${path}" is under an API prefix — the API is never cached`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (config.noShellFallback?.includes(shellPath)) {
|
|
105
|
+
throw new Error(`shell worker: the shell path "${shellPath}" cannot also be in noShellFallback`);
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
cachePrefix: config.cachePrefix,
|
|
109
|
+
version: config.version,
|
|
110
|
+
cacheName: `${config.cachePrefix}${config.version}`,
|
|
111
|
+
precache,
|
|
112
|
+
apiPrefixes,
|
|
113
|
+
passthroughPrefixes: config.passthroughPrefixes ?? [],
|
|
114
|
+
noShellFallback: config.noShellFallback ?? [],
|
|
115
|
+
assetExtensions: config.assetExtensions ?? DEFAULT_ASSET_EXT,
|
|
116
|
+
shellPath,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Wire `install`, `activate` and `fetch` onto `scope` (the worker's `self`).
|
|
121
|
+
* Returns the resolved config, so an app can read `cacheName` for its own use.
|
|
122
|
+
*/
|
|
123
|
+
export function installShellWorker(scope, config) {
|
|
124
|
+
const resolved = resolveShellWorkerConfig(config);
|
|
125
|
+
const { caches } = scope;
|
|
126
|
+
// Written after the response is handed back, like roms' `cache.put` — but kept
|
|
127
|
+
// alive with `waitUntil` so the worker is not stopped mid-write, and swallowed on
|
|
128
|
+
// failure: a full quota must not turn a good network response into an error.
|
|
129
|
+
const store = (event, route, response) => {
|
|
130
|
+
if (!shouldCache(route) || !response.ok)
|
|
131
|
+
return;
|
|
132
|
+
const copy = response.clone();
|
|
133
|
+
event.waitUntil(caches
|
|
134
|
+
.open(resolved.cacheName)
|
|
135
|
+
.then((cache) => cache.put(event.request, copy))
|
|
136
|
+
.catch(() => undefined));
|
|
137
|
+
};
|
|
138
|
+
const cacheFirst = async (event) => {
|
|
139
|
+
const cached = await caches.match(event.request);
|
|
140
|
+
if (cached)
|
|
141
|
+
return cached;
|
|
142
|
+
const response = await scope.fetch(event.request);
|
|
143
|
+
store(event, 'asset', response);
|
|
144
|
+
return response;
|
|
145
|
+
};
|
|
146
|
+
const networkFirst = async (event) => {
|
|
147
|
+
const { request } = event;
|
|
148
|
+
try {
|
|
149
|
+
const response = await scope.fetch(request);
|
|
150
|
+
store(event, 'navigate', response);
|
|
151
|
+
return response;
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
// Offline. The exact URL first, then the same path ignoring the query — roms'
|
|
155
|
+
// frame is `/emulator-frame.html?system=nes`, and one cached copy answers for
|
|
156
|
+
// every console.
|
|
157
|
+
const cached = (await caches.match(request)) ?? (await caches.match(request, { ignoreSearch: true }));
|
|
158
|
+
if (cached)
|
|
159
|
+
return cached;
|
|
160
|
+
if (mayFallBackToShell(new URL(request.url).pathname, resolved)) {
|
|
161
|
+
const shell = await caches.match(resolved.shellPath);
|
|
162
|
+
if (shell)
|
|
163
|
+
return shell;
|
|
164
|
+
}
|
|
165
|
+
// Nothing honest to serve: reject, and the browser shows its own offline page
|
|
166
|
+
// rather than a document that is not the one asked for.
|
|
167
|
+
throw error;
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
scope.addEventListener('install', (event) => {
|
|
171
|
+
event.waitUntil(caches
|
|
172
|
+
.open(resolved.cacheName)
|
|
173
|
+
.then((cache) => cache.addAll([...resolved.precache]))
|
|
174
|
+
.then(() => scope.skipWaiting()));
|
|
175
|
+
});
|
|
176
|
+
scope.addEventListener('activate', (event) => {
|
|
177
|
+
event.waitUntil(caches
|
|
178
|
+
.keys()
|
|
179
|
+
.then((keys) => Promise.all(keys
|
|
180
|
+
.filter((key) => key.startsWith(resolved.cachePrefix) && key !== resolved.cacheName)
|
|
181
|
+
.map((key) => caches.delete(key))))
|
|
182
|
+
.then(() => scope.clients.claim()));
|
|
183
|
+
});
|
|
184
|
+
scope.addEventListener('fetch', (event) => {
|
|
185
|
+
const url = new URL(event.request.url);
|
|
186
|
+
const route = classifyRequest({
|
|
187
|
+
method: event.request.method,
|
|
188
|
+
sameOrigin: url.origin === scope.location.origin,
|
|
189
|
+
pathname: url.pathname,
|
|
190
|
+
isNavigate: event.request.mode === 'navigate',
|
|
191
|
+
}, resolved);
|
|
192
|
+
if (route === 'asset')
|
|
193
|
+
event.respondWith(cacheFirst(event));
|
|
194
|
+
else if (route === 'navigate')
|
|
195
|
+
event.respondWith(networkFirst(event));
|
|
196
|
+
// `api` and `passthrough`: no respondWith, so the browser goes to the network as
|
|
197
|
+
// if this worker did not exist. Never a cache read, never a cache write.
|
|
198
|
+
});
|
|
199
|
+
return resolved;
|
|
200
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { NavItem } from '../navigation';
|
|
1
|
+
import type { NavItem } from '../navigation/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* The initials of a multi-word label (`'Query Builder'` → `'qb'`). Single-word labels
|
|
4
4
|
* return `''` (their prefix already matches via the label itself). Powers initialism
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { fuzzyRankItems, searchInitials, } from './fuzzyRank';
|
|
2
|
-
export { formatHotkey, isApplePlatform, matchHotkey, type ParsedHotkey, parseHotkey, } from './hotkeys';
|
|
3
|
-
export { type ShortcutEntry, ShortcutRegistry, shortcutRegistry, } from './ShortcutRegistry';
|
|
1
|
+
export { fuzzyRankItems, searchInitials, } from './fuzzyRank.js';
|
|
2
|
+
export { formatHotkey, isApplePlatform, matchHotkey, type ParsedHotkey, parseHotkey, } from './hotkeys.js';
|
|
3
|
+
export { type ShortcutEntry, ShortcutRegistry, shortcutRegistry, } from './ShortcutRegistry.js';
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
// browser dependency beyond optional `navigator`/event reads — usable in a startup
|
|
4
4
|
// module, a server test, or the React layer alike. The `CommandPalette` component +
|
|
5
5
|
// its hooks live in `cursedbelt/react` and build on exactly this.
|
|
6
|
-
export { fuzzyRankItems, searchInitials, } from './fuzzyRank';
|
|
7
|
-
export { formatHotkey, isApplePlatform, matchHotkey, parseHotkey, } from './hotkeys';
|
|
8
|
-
export { ShortcutRegistry, shortcutRegistry, } from './ShortcutRegistry';
|
|
6
|
+
export { fuzzyRankItems, searchInitials, } from './fuzzyRank.js';
|
|
7
|
+
export { formatHotkey, isApplePlatform, matchHotkey, parseHotkey, } from './hotkeys.js';
|
|
8
|
+
export { ShortcutRegistry, shortcutRegistry, } from './ShortcutRegistry.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** The fleet's sharing/access vocabulary — see `./model.ts` for the whole
|
|
2
2
|
* contract. Storage lives in `cursedbelt-server/sharing`, the UI in
|
|
3
3
|
* `cursedbelt/react/sharing`; both speak these words. */
|
|
4
|
-
export { accessMeets, describeAccess, describeShareEvent, isShareAccess, isShareLevel, isShareSubjectType, levelsMeeting, normalizeSubject, normalizeSubjectId, resolveAccess, resourceKey, sameResource, sameSubject, SHARE_ACTIONS, strongerAccess, } from "./model";
|
|
5
|
-
export type { ShareAccess, ShareAction, ShareEvent, ShareGrant, ShareGroup, ShareGroupMember, ShareLevel, ShareResource, ShareSubject, ShareSubjectType, ShareViewer, } from "./model";
|
|
4
|
+
export { accessMeets, describeAccess, describeShareEvent, isShareAccess, isShareLevel, isShareSubjectType, levelsMeeting, normalizeSubject, normalizeSubjectId, resolveAccess, resourceKey, sameResource, sameSubject, SHARE_ACTIONS, strongerAccess, } from "./model.js";
|
|
5
|
+
export type { ShareAccess, ShareAction, ShareEvent, ShareGrant, ShareGroup, ShareGroupMember, ShareLevel, ShareResource, ShareSubject, ShareSubjectType, ShareViewer, } from "./model.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/** The fleet's sharing/access vocabulary — see `./model.ts` for the whole
|
|
2
2
|
* contract. Storage lives in `cursedbelt-server/sharing`, the UI in
|
|
3
3
|
* `cursedbelt/react/sharing`; both speak these words. */
|
|
4
|
-
export { accessMeets, describeAccess, describeShareEvent, isShareAccess, isShareLevel, isShareSubjectType, levelsMeeting, normalizeSubject, normalizeSubjectId, resolveAccess, resourceKey, sameResource, sameSubject, SHARE_ACTIONS, strongerAccess, } from "./model";
|
|
4
|
+
export { accessMeets, describeAccess, describeShareEvent, isShareAccess, isShareLevel, isShareSubjectType, levelsMeeting, normalizeSubject, normalizeSubjectId, resolveAccess, resourceKey, sameResource, sameSubject, SHARE_ACTIONS, strongerAccess, } from "./model.js";
|
|
@@ -50,8 +50,8 @@ export interface TokenDef<S extends z.ZodType = z.ZodType> {
|
|
|
50
50
|
* They used to be a second, divergent declaration of the same names — see the
|
|
51
51
|
* unification note on `CCWireMarshaller` (05 §B1).
|
|
52
52
|
*/
|
|
53
|
-
import type { CCWireMarshaller } from '../wire/marshalling';
|
|
54
|
-
export { type CCWireMarshaller, MARSHALLER_WORKER_OFFLOAD_BYTES, requiresWorkerOffload, } from '../wire/marshalling';
|
|
53
|
+
import type { CCWireMarshaller } from '../wire/marshalling.js';
|
|
54
|
+
export { type CCWireMarshaller, MARSHALLER_WORKER_OFFLOAD_BYTES, requiresWorkerOffload, } from '../wire/marshalling.js';
|
|
55
55
|
export type TokenRegistryIssueCode = 'token-collision' | 'token-namespace-violation' | 'subtype-inversion' | 'token-supertype-missing' | 'token-subtype-cycle' | 'token-sample-invalid';
|
|
56
56
|
export interface TokenRegistryIssue {
|
|
57
57
|
code: TokenRegistryIssueCode;
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* (the core would stop compiling the moment the plugin is deleted).
|
|
20
20
|
*/
|
|
21
21
|
import { z } from 'zod';
|
|
22
|
-
export { MARSHALLER_WORKER_OFFLOAD_BYTES, requiresWorkerOffload, } from '../wire/marshalling';
|
|
22
|
+
export { MARSHALLER_WORKER_OFFLOAD_BYTES, requiresWorkerOffload, } from '../wire/marshalling.js';
|
|
23
23
|
const TOKEN_ID_RE = /^[a-z][a-z0-9-]*:[a-z0-9-]+$/;
|
|
24
24
|
const EXTENSION_ID_RE = /^x-[a-z0-9-]+:[a-z0-9-]+$/;
|
|
25
25
|
export const isExtensionTokenId = (id) => id.startsWith('x-');
|
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
* the saved size on app boot (before React mounts → no flash); the React control +
|
|
5
5
|
* hook live in `cursedbelt/react`.
|
|
6
6
|
*/
|
|
7
|
-
export { clampUiScale, DEFAULT_UI_SCALE, MAX_UI_SCALE, MIN_UI_SCALE, nearestUiScaleLevel, stepUiScale, UI_SCALE_LEVELS, UI_SCALE_STEP, type UiScaleLevel, type UiScaleLevelId, uiScaleToFontSize, } from './scale';
|
|
8
|
-
export { applyUiScaleToDocument, createUiScaleStore, getUiScale, initUiScale, setUiScale, subscribeUiScale, UI_SCALE_STORAGE_KEY, type UiScaleStorage, type UiScaleStore, type UiScaleStoreOptions, uiScaleStore, } from './uiScaleStore';
|
|
7
|
+
export { clampUiScale, DEFAULT_UI_SCALE, MAX_UI_SCALE, MIN_UI_SCALE, nearestUiScaleLevel, stepUiScale, UI_SCALE_LEVELS, UI_SCALE_STEP, type UiScaleLevel, type UiScaleLevelId, uiScaleToFontSize, } from './scale.js';
|
|
8
|
+
export { applyUiScaleToDocument, createUiScaleStore, getUiScale, initUiScale, setUiScale, subscribeUiScale, UI_SCALE_STORAGE_KEY, type UiScaleStorage, type UiScaleStore, type UiScaleStoreOptions, uiScaleStore, } from './uiScaleStore.js';
|
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
* the saved size on app boot (before React mounts → no flash); the React control +
|
|
5
5
|
* hook live in `cursedbelt/react`.
|
|
6
6
|
*/
|
|
7
|
-
export { clampUiScale, DEFAULT_UI_SCALE, MAX_UI_SCALE, MIN_UI_SCALE, nearestUiScaleLevel, stepUiScale, UI_SCALE_LEVELS, UI_SCALE_STEP, uiScaleToFontSize, } from './scale';
|
|
8
|
-
export { applyUiScaleToDocument, createUiScaleStore, getUiScale, initUiScale, setUiScale, subscribeUiScale, UI_SCALE_STORAGE_KEY, uiScaleStore, } from './uiScaleStore';
|
|
7
|
+
export { clampUiScale, DEFAULT_UI_SCALE, MAX_UI_SCALE, MIN_UI_SCALE, nearestUiScaleLevel, stepUiScale, UI_SCALE_LEVELS, UI_SCALE_STEP, uiScaleToFontSize, } from './scale.js';
|
|
8
|
+
export { applyUiScaleToDocument, createUiScaleStore, getUiScale, initUiScale, setUiScale, subscribeUiScale, UI_SCALE_STORAGE_KEY, uiScaleStore, } from './uiScaleStore.js';
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* real store with fakes; the exported default singleton binds them to
|
|
9
9
|
* `localStorage` + the `<html>` element.
|
|
10
10
|
*/
|
|
11
|
-
import { clampUiScale, DEFAULT_UI_SCALE, stepUiScale, uiScaleToFontSize } from './scale';
|
|
11
|
+
import { clampUiScale, DEFAULT_UI_SCALE, stepUiScale, uiScaleToFontSize } from './scale.js';
|
|
12
12
|
export const UI_SCALE_STORAGE_KEY = 'cwip.uiScale';
|
|
13
13
|
export function createUiScaleStore(options = {}) {
|
|
14
14
|
const { storage = null, apply, key = UI_SCALE_STORAGE_KEY } = options;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* and the worker imports it.
|
|
9
9
|
*/
|
|
10
10
|
import { z } from 'zod';
|
|
11
|
-
import { serveMarshalWorker } from '../marshalWorker';
|
|
11
|
+
import { serveMarshalWorker } from '../marshalWorker.js';
|
|
12
12
|
const schema = z.object({ rows: z.array(z.object({ id: z.string() })) });
|
|
13
13
|
await serveMarshalWorker({
|
|
14
14
|
id: 'rows',
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* `wireHub` is re-exported from `cursedbelt-cc/client` as well; that entry is where
|
|
12
12
|
* a shell host looks, this one is where the wire tier lives.
|
|
13
13
|
*/
|
|
14
|
-
export { type CCWireMarshaller, createMarshallerRegistry, MARSHALLER_PAYLOAD_TOO_LARGE, MARSHALLER_SCHEMA_VIOLATION, MARSHALLER_VALIDATION_FAILED, MARSHALLER_WORKER_OFFLOAD_BYTES, type MarshallerRegistry, type MarshalOptions, type MarshalWorker, marshalInbound, payloadBytes, requiresWorkerOffload, } from './marshalling';
|
|
15
|
-
export { createMarshalWorkerClient, MARSHAL_WORKER_DEFAULT_TIMEOUT_MS, MARSHALLER_WORKER_FAILED, MARSHALLER_WORKER_TIMEOUT, type MarshalWorkerClient, type MarshalWorkerClientOptions, type MarshalWorkerRequest, type MarshalWorkerResponse, serveMarshalWorker, } from './marshalWorker';
|
|
16
|
-
export { createMarshalledIngress, INGRESS_TOKEN_UNKNOWN, type MarshalledIngress, type MarshalledIngressOptions, } from './ingress';
|
|
17
|
-
export { createInstanceRuntime, createWireHub, type InstanceRuntime, type InstanceRuntimeOptions, type WireEnvelope, type WireHub, type WireHubOptions, } from './wireHub';
|
|
14
|
+
export { type CCWireMarshaller, createMarshallerRegistry, MARSHALLER_PAYLOAD_TOO_LARGE, MARSHALLER_SCHEMA_VIOLATION, MARSHALLER_VALIDATION_FAILED, MARSHALLER_WORKER_OFFLOAD_BYTES, type MarshallerRegistry, type MarshalOptions, type MarshalWorker, marshalInbound, payloadBytes, requiresWorkerOffload, } from './marshalling.js';
|
|
15
|
+
export { createMarshalWorkerClient, MARSHAL_WORKER_DEFAULT_TIMEOUT_MS, MARSHALLER_WORKER_FAILED, MARSHALLER_WORKER_TIMEOUT, type MarshalWorkerClient, type MarshalWorkerClientOptions, type MarshalWorkerRequest, type MarshalWorkerResponse, serveMarshalWorker, } from './marshalWorker.js';
|
|
16
|
+
export { createMarshalledIngress, INGRESS_TOKEN_UNKNOWN, type MarshalledIngress, type MarshalledIngressOptions, } from './ingress.js';
|
|
17
|
+
export { createInstanceRuntime, createWireHub, type InstanceRuntime, type InstanceRuntimeOptions, type WireEnvelope, type WireHub, type WireHubOptions, } from './wireHub.js';
|
package/dist/core/wire/index.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* `wireHub` is re-exported from `cursedbelt-cc/client` as well; that entry is where
|
|
12
12
|
* a shell host looks, this one is where the wire tier lives.
|
|
13
13
|
*/
|
|
14
|
-
export { createMarshallerRegistry, MARSHALLER_PAYLOAD_TOO_LARGE, MARSHALLER_SCHEMA_VIOLATION, MARSHALLER_VALIDATION_FAILED, MARSHALLER_WORKER_OFFLOAD_BYTES, marshalInbound, payloadBytes, requiresWorkerOffload, } from './marshalling';
|
|
15
|
-
export { createMarshalWorkerClient, MARSHAL_WORKER_DEFAULT_TIMEOUT_MS, MARSHALLER_WORKER_FAILED, MARSHALLER_WORKER_TIMEOUT, serveMarshalWorker, } from './marshalWorker';
|
|
16
|
-
export { createMarshalledIngress, INGRESS_TOKEN_UNKNOWN, } from './ingress';
|
|
17
|
-
export { createInstanceRuntime, createWireHub, } from './wireHub';
|
|
14
|
+
export { createMarshallerRegistry, MARSHALLER_PAYLOAD_TOO_LARGE, MARSHALLER_SCHEMA_VIOLATION, MARSHALLER_VALIDATION_FAILED, MARSHALLER_WORKER_OFFLOAD_BYTES, marshalInbound, payloadBytes, requiresWorkerOffload, } from './marshalling.js';
|
|
15
|
+
export { createMarshalWorkerClient, MARSHAL_WORKER_DEFAULT_TIMEOUT_MS, MARSHALLER_WORKER_FAILED, MARSHALLER_WORKER_TIMEOUT, serveMarshalWorker, } from './marshalWorker.js';
|
|
16
|
+
export { createMarshalledIngress, INGRESS_TOKEN_UNKNOWN, } from './ingress.js';
|
|
17
|
+
export { createInstanceRuntime, createWireHub, } from './wireHub.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type MarshallerRegistry } from './marshalling';
|
|
1
|
+
import { type MarshallerRegistry } from './marshalling.js';
|
|
2
2
|
/** No marshaller is registered for the token an ingress was asked to feed. */
|
|
3
3
|
export declare const INGRESS_TOKEN_UNKNOWN = "INGRESS_TOKEN_UNKNOWN";
|
|
4
4
|
export interface MarshalledIngressOptions {
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
* A CSV import is the same three lines with a different marshaller and a
|
|
51
51
|
* different service call. Neither needs to know that a worker exists.
|
|
52
52
|
*/
|
|
53
|
-
import { AppError } from '../../shared/errors';
|
|
54
|
-
import { createMarshalWorkerClient } from './marshalWorker';
|
|
55
|
-
import { marshalInbound, } from './marshalling';
|
|
53
|
+
import { AppError } from '../../shared/errors.js';
|
|
54
|
+
import { createMarshalWorkerClient } from './marshalWorker.js';
|
|
55
|
+
import { marshalInbound, } from './marshalling.js';
|
|
56
56
|
/** No marshaller is registered for the token an ingress was asked to feed. */
|
|
57
57
|
export const INGRESS_TOKEN_UNKNOWN = 'INGRESS_TOKEN_UNKNOWN';
|
|
58
58
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type CCWireMarshaller, MARSHALLER_SCHEMA_VIOLATION, MARSHALLER_VALIDATION_FAILED, type MarshalWorker } from './marshalling';
|
|
1
|
+
import { type CCWireMarshaller, MARSHALLER_SCHEMA_VIOLATION, MARSHALLER_VALIDATION_FAILED, type MarshalWorker } from './marshalling.js';
|
|
2
2
|
export declare const MARSHALLER_WORKER_FAILED = "MARSHALLER_WORKER_FAILED";
|
|
3
3
|
export declare const MARSHALLER_WORKER_TIMEOUT = "MARSHALLER_WORKER_TIMEOUT";
|
|
4
4
|
/** How long one payload may occupy the worker before the host gives up. */
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
* inside the server branch — a static import would put a Node builtin in the
|
|
34
34
|
* module graph of every client bundle that touches wire code.
|
|
35
35
|
*/
|
|
36
|
-
import { AppError } from '../../shared/errors';
|
|
37
|
-
import { MARSHALLER_SCHEMA_VIOLATION, MARSHALLER_VALIDATION_FAILED, } from './marshalling';
|
|
36
|
+
import { AppError } from '../../shared/errors.js';
|
|
37
|
+
import { MARSHALLER_SCHEMA_VIOLATION, MARSHALLER_VALIDATION_FAILED, } from './marshalling.js';
|
|
38
38
|
export const MARSHALLER_WORKER_FAILED = 'MARSHALLER_WORKER_FAILED';
|
|
39
39
|
export const MARSHALLER_WORKER_TIMEOUT = 'MARSHALLER_WORKER_TIMEOUT';
|
|
40
40
|
/** How long one payload may occupy the worker before the host gives up. */
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
* - Inconsistency errors (e.g., second chunk claims different total count) delete the entry immediately; recovery requires retransmitting all chunks from the client
|
|
62
62
|
* - The service itself is a singleton; do NOT create multiple instances per server or request thread
|
|
63
63
|
*/
|
|
64
|
-
import type { CtgrDecoded } from './types';
|
|
64
|
+
import type { CtgrDecoded } from './types.js';
|
|
65
65
|
/**
|
|
66
66
|
* Configuration for ChunkAccumulator resource limits and timing behavior.
|
|
67
67
|
*
|
|
@@ -61,8 +61,8 @@
|
|
|
61
61
|
* - Inconsistency errors (e.g., second chunk claims different total count) delete the entry immediately; recovery requires retransmitting all chunks from the client
|
|
62
62
|
* - The service itself is a singleton; do NOT create multiple instances per server or request thread
|
|
63
63
|
*/
|
|
64
|
-
import { decodePayload, parseChunk } from './codec';
|
|
65
|
-
import { sha256Hex } from './digest';
|
|
64
|
+
import { decodePayload, parseChunk } from './codec.js';
|
|
65
|
+
import { sha256Hex } from './digest.js';
|
|
66
66
|
/**
|
|
67
67
|
* ChunkAccumulator — The hardened service for multi-chunk payload assembly.
|
|
68
68
|
*
|
package/dist/ctgr/chunkStore.js
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
* It NEVER throws: a malformed/corrupt/oversized payload returns an `Error` the
|
|
10
10
|
* middleware maps to a 400; an intermediate chunk returns `false` (→ 202).
|
|
11
11
|
*/
|
|
12
|
-
import { decodePayload, parseChunk } from './codec';
|
|
13
|
-
import { sha256Hex } from './digest';
|
|
12
|
+
import { decodePayload, parseChunk } from './codec.js';
|
|
13
|
+
import { sha256Hex } from './digest.js';
|
|
14
14
|
export class ChunkStore {
|
|
15
15
|
entries = new Map();
|
|
16
16
|
maxInFlight;
|
package/dist/ctgr/codec.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type CtgrDecoded, type CtgrMethod, type EncodedRequest, type EncodeOpts, type UploadedFile } from './types';
|
|
1
|
+
import { type CtgrDecoded, type CtgrMethod, type EncodedRequest, type EncodeOpts, type UploadedFile } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Encode a mutating request into one or more `/ctgr<XX>` GET-twin chunks. Small
|
|
4
4
|
* bodies become a single chunk; large bodies gzip (when over the threshold) and split
|
package/dist/ctgr/codec.js
CHANGED
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
* double-base64'd and whose swap/reverse was trivially-reversible obfuscation, not
|
|
12
12
|
* protection — the real protection (getOnly JWT claim + CSRF guard) is unchanged.
|
|
13
13
|
*/
|
|
14
|
-
import { fromBase64, fromBase64url, toBase64url } from './base64url';
|
|
15
|
-
import { gunzip, gzip } from './compress';
|
|
16
|
-
import { crc32 } from './crc32';
|
|
17
|
-
import { sha256Hex } from './digest';
|
|
18
|
-
import { ABBREV_TO_METHOD, CTGR_WIRE_VERSION, METHOD_TO_ABBREV, } from './types';
|
|
14
|
+
import { fromBase64, fromBase64url, toBase64url } from './base64url.js';
|
|
15
|
+
import { gunzip, gzip } from './compress.js';
|
|
16
|
+
import { crc32 } from './crc32.js';
|
|
17
|
+
import { sha256Hex } from './digest.js';
|
|
18
|
+
import { ABBREV_TO_METHOD, CTGR_WIRE_VERSION, METHOD_TO_ABBREV, } from './types.js';
|
|
19
19
|
const DEFAULT_CHUNK_SIZE = 1800;
|
|
20
20
|
const DEFAULT_GZIP_THRESHOLD = 1024;
|
|
21
21
|
const textEncoder = new TextEncoder();
|
package/dist/ctgr/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { fromBase64, fromBase64url, toBase64, toBase64url } from './base64url';
|
|
2
|
-
export { ChunkAccumulator, type ChunkAccumulatorConfig, } from './chunkAccumulator';
|
|
3
|
-
export { ChunkStore, type ChunkStoreOpts } from './chunkStore';
|
|
4
|
-
export { decodePayload, decodeRequest, encodeRequest, extractFiles, type ParsedChunk, parseChunk, } from './codec';
|
|
5
|
-
export { gunzip, gzip } from './compress';
|
|
6
|
-
export { crc32 } from './crc32';
|
|
7
|
-
export { sha256Hex } from './digest';
|
|
8
|
-
export { ABBREV_TO_METHOD, CTGR_WIRE_VERSION, type CtgrAbbrev, type CtgrDecoded, type CtgrMethod, type EncodedChunk, type EncodedRequest, type EncodeOpts, METHOD_TO_ABBREV, type SerializedFile, type UploadedFile, } from './types';
|
|
9
|
-
export { decodeV0Payload, V0ChunkStore, type V0ChunkStoreOpts } from './v0compat';
|
|
1
|
+
export { fromBase64, fromBase64url, toBase64, toBase64url } from './base64url.js';
|
|
2
|
+
export { ChunkAccumulator, type ChunkAccumulatorConfig, } from './chunkAccumulator.js';
|
|
3
|
+
export { ChunkStore, type ChunkStoreOpts } from './chunkStore.js';
|
|
4
|
+
export { decodePayload, decodeRequest, encodeRequest, extractFiles, type ParsedChunk, parseChunk, } from './codec.js';
|
|
5
|
+
export { gunzip, gzip } from './compress.js';
|
|
6
|
+
export { crc32 } from './crc32.js';
|
|
7
|
+
export { sha256Hex } from './digest.js';
|
|
8
|
+
export { ABBREV_TO_METHOD, CTGR_WIRE_VERSION, type CtgrAbbrev, type CtgrDecoded, type CtgrMethod, type EncodedChunk, type EncodedRequest, type EncodeOpts, METHOD_TO_ABBREV, type SerializedFile, type UploadedFile, } from './types.js';
|
|
9
|
+
export { decodeV0Payload, V0ChunkStore, type V0ChunkStoreOpts } from './v0compat.js';
|
package/dist/ctgr/index.js
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
* The ChunkAccumulator is the primary abstraction for multi-chunk payload assembly;
|
|
7
7
|
* ChunkStore is kept for backward compatibility (they are identical implementations).
|
|
8
8
|
*/
|
|
9
|
-
export { fromBase64, fromBase64url, toBase64, toBase64url } from './base64url';
|
|
10
|
-
export { ChunkAccumulator, } from './chunkAccumulator';
|
|
11
|
-
export { ChunkStore } from './chunkStore';
|
|
12
|
-
export { decodePayload, decodeRequest, encodeRequest, extractFiles, parseChunk, } from './codec';
|
|
13
|
-
export { gunzip, gzip } from './compress';
|
|
14
|
-
export { crc32 } from './crc32';
|
|
15
|
-
export { sha256Hex } from './digest';
|
|
16
|
-
export { ABBREV_TO_METHOD, CTGR_WIRE_VERSION, METHOD_TO_ABBREV, } from './types';
|
|
17
|
-
export { decodeV0Payload, V0ChunkStore } from './v0compat';
|
|
9
|
+
export { fromBase64, fromBase64url, toBase64, toBase64url } from './base64url.js';
|
|
10
|
+
export { ChunkAccumulator, } from './chunkAccumulator.js';
|
|
11
|
+
export { ChunkStore } from './chunkStore.js';
|
|
12
|
+
export { decodePayload, decodeRequest, encodeRequest, extractFiles, parseChunk, } from './codec.js';
|
|
13
|
+
export { gunzip, gzip } from './compress.js';
|
|
14
|
+
export { crc32 } from './crc32.js';
|
|
15
|
+
export { sha256Hex } from './digest.js';
|
|
16
|
+
export { ABBREV_TO_METHOD, CTGR_WIRE_VERSION, METHOD_TO_ABBREV, } from './types.js';
|
|
17
|
+
export { decodeV0Payload, V0ChunkStore } from './v0compat.js';
|
package/dist/ctgr/v0compat.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CtgrDecoded, CtgrMethod } from './types';
|
|
1
|
+
import type { CtgrDecoded, CtgrMethod } from './types.js';
|
|
2
2
|
/** Reverse the v0 client pipeline (`encode→reverse→swap→encode→swap`) and parse JSON. */
|
|
3
3
|
export declare function decodeV0Payload(encoded: string): unknown;
|
|
4
4
|
export interface V0ChunkStoreOpts {
|
package/dist/ctgr/v0compat.js
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
* heuristic, since v1 always sets `_cv=1`. v0 carried the method only in the path
|
|
10
10
|
* (`/ctgr<XX>`), so the middleware passes the path-derived method in.
|
|
11
11
|
*/
|
|
12
|
-
import { fromBase64 } from './base64url';
|
|
13
|
-
import { extractFiles } from './codec';
|
|
12
|
+
import { fromBase64 } from './base64url.js';
|
|
13
|
+
import { extractFiles } from './codec.js';
|
|
14
14
|
const decodeBase64Utf8 = (str) => new TextDecoder().decode(fromBase64(str));
|
|
15
15
|
const reverseString = (str) => str.split('').reverse().join('');
|
|
16
16
|
const swapEnds = (str) => {
|
package/dist/index.d.ts
CHANGED
|
@@ -11,5 +11,5 @@
|
|
|
11
11
|
* drag 47 dependencies into every consumer.
|
|
12
12
|
*/
|
|
13
13
|
export declare const VERSION = "1.0.0";
|
|
14
|
-
export { contrastText } from './core/color';
|
|
15
|
-
export { isSiteCopyKey, SITE_COPY_BAKED_ONLY, SITE_COPY_DEFAULTS, SITE_COPY_KEYS, SITE_COPY_MAX_VALUE_LENGTH, type SiteCopyKey, } from './core/site/siteCopy';
|
|
14
|
+
export { contrastText } from './core/color.js';
|
|
15
|
+
export { isSiteCopyKey, SITE_COPY_BAKED_ONLY, SITE_COPY_DEFAULTS, SITE_COPY_KEYS, SITE_COPY_MAX_VALUE_LENGTH, type SiteCopyKey, } from './core/site/siteCopy.js';
|
package/dist/index.js
CHANGED
|
@@ -13,5 +13,5 @@
|
|
|
13
13
|
export const VERSION = '1.0.0';
|
|
14
14
|
// The two root-level conveniences the pre-split "." barrel actually served:
|
|
15
15
|
// the WCAG readable-foreground picker and the baked marketing-copy contract.
|
|
16
|
-
export { contrastText } from './core/color';
|
|
17
|
-
export { isSiteCopyKey, SITE_COPY_BAKED_ONLY, SITE_COPY_DEFAULTS, SITE_COPY_KEYS, SITE_COPY_MAX_VALUE_LENGTH, } from './core/site/siteCopy';
|
|
16
|
+
export { contrastText } from './core/color.js';
|
|
17
|
+
export { isSiteCopyKey, SITE_COPY_BAKED_ONLY, SITE_COPY_DEFAULTS, SITE_COPY_KEYS, SITE_COPY_MAX_VALUE_LENGTH, } from './core/site/siteCopy.js';
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { installCheapDomInspect } from "./domInspect";
|
|
2
|
-
export { asBody, bytesResponse, bytesStream } from "./bytes";
|
|
3
|
-
export { type FetchImpl, fakeFetch } from "./fakeFetch";
|
|
1
|
+
export { installCheapDomInspect } from "./domInspect.js";
|
|
2
|
+
export { asBody, bytesResponse, bytesStream } from "./bytes.js";
|
|
3
|
+
export { type FetchImpl, fakeFetch } from "./fakeFetch.js";
|
package/dist/testing/index.js
CHANGED
|
@@ -6,6 +6,6 @@
|
|
|
6
6
|
// can `import { installCheapDomInspect } from "cursedbelt-core/testing"` instead of
|
|
7
7
|
// keeping a ~60-line hand-port of domInspect.ts — the file already lived here,
|
|
8
8
|
// it just had no export.
|
|
9
|
-
export { installCheapDomInspect } from "./domInspect";
|
|
10
|
-
export { asBody, bytesResponse, bytesStream } from "./bytes";
|
|
11
|
-
export { fakeFetch } from "./fakeFetch";
|
|
9
|
+
export { installCheapDomInspect } from "./domInspect.js";
|
|
10
|
+
export { asBody, bytesResponse, bytesStream } from "./bytes.js";
|
|
11
|
+
export { fakeFetch } from "./fakeFetch.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cursedbelt-core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"license": "ISC",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Framework-agnostic core of the cursedbelt split — isomorphic domain logic. cwip below it, cursedbelt-server and cursedbelt (react) above it.",
|
|
@@ -251,6 +251,12 @@
|
|
|
251
251
|
"source": "./src/core/net/reconnectSchedule.ts",
|
|
252
252
|
"import": "./dist/core/net/reconnectSchedule.js"
|
|
253
253
|
},
|
|
254
|
+
"./offline/shell-worker": {
|
|
255
|
+
"types": "./dist/core/offline/shellWorker.d.ts",
|
|
256
|
+
"bun": "./src/core/offline/shellWorker.ts",
|
|
257
|
+
"source": "./src/core/offline/shellWorker.ts",
|
|
258
|
+
"import": "./dist/core/offline/shellWorker.js"
|
|
259
|
+
},
|
|
254
260
|
"./palette": {
|
|
255
261
|
"types": "./dist/core/palette/index.d.ts",
|
|
256
262
|
"bun": "./src/core/palette/index.ts",
|
|
@@ -362,7 +368,7 @@
|
|
|
362
368
|
},
|
|
363
369
|
"dependencies": {
|
|
364
370
|
"@leeoniya/ufuzzy": "^1.0.19",
|
|
365
|
-
"cwip": "^4.
|
|
371
|
+
"cwip": "^4.6.0"
|
|
366
372
|
},
|
|
367
373
|
"peerDependencies": {
|
|
368
374
|
"zod": "^4.4.0"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, expect, it } from 'bun:test';
|
|
2
|
-
import { AppConfigSchema, effectiveSignupMode, featureKeysOf, resolveInstanceFeatures, ROUTE_PATH_RE } from './appConfig';
|
|
2
|
+
import { AppConfigSchema, effectiveSignupMode, featureKeysOf, resolveInstanceFeatures, ROUTE_PATH_RE } from './appConfig.js';
|
|
3
3
|
|
|
4
4
|
const base = (over: Record<string, unknown> = {}) => ({
|
|
5
5
|
configVersion: 1,
|
|
@@ -12,10 +12,10 @@ export {
|
|
|
12
12
|
describeActivityResource,
|
|
13
13
|
isActivityAction,
|
|
14
14
|
isActivityOutcome,
|
|
15
|
-
} from "./model";
|
|
15
|
+
} from "./model.js";
|
|
16
16
|
export type {
|
|
17
17
|
ActivityEvent,
|
|
18
18
|
ActivityEventInput,
|
|
19
19
|
ActivityOutcome,
|
|
20
20
|
ActivityResource,
|
|
21
|
-
} from "./model";
|
|
21
|
+
} from "./model.js";
|