@braidlabs/core 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.
- package/README.md +123 -0
- package/package.json +37 -0
- package/src/adapters/adapter.d.ts +75 -0
- package/src/adapters/adapter.js +35 -0
- package/src/adapters/adapter.js.map +1 -0
- package/src/adapters/compat-adapter.d.ts +27 -0
- package/src/adapters/compat-adapter.js +113 -0
- package/src/adapters/compat-adapter.js.map +1 -0
- package/src/adapters/custom-element-adapter.d.ts +21 -0
- package/src/adapters/custom-element-adapter.js +91 -0
- package/src/adapters/custom-element-adapter.js.map +1 -0
- package/src/compat/born-inert-scripts.d.ts +30 -0
- package/src/compat/born-inert-scripts.js +85 -0
- package/src/compat/born-inert-scripts.js.map +1 -0
- package/src/compat/document-facade.d.ts +44 -0
- package/src/compat/document-facade.js +104 -0
- package/src/compat/document-facade.js.map +1 -0
- package/src/compat/document-member-classification.d.ts +30 -0
- package/src/compat/document-member-classification.js +64 -0
- package/src/compat/document-member-classification.js.map +1 -0
- package/src/compat/document-overrides.d.ts +44 -0
- package/src/compat/document-overrides.js +225 -0
- package/src/compat/document-overrides.js.map +1 -0
- package/src/compat/document-surface.generated.d.ts +21 -0
- package/src/compat/document-surface.generated.js +292 -0
- package/src/compat/document-surface.generated.js.map +1 -0
- package/src/compat/fragment-boundary.d.ts +14 -0
- package/src/compat/fragment-boundary.js +335 -0
- package/src/compat/fragment-boundary.js.map +1 -0
- package/src/compat/metadata.d.ts +15 -0
- package/src/compat/metadata.js +21 -0
- package/src/compat/metadata.js.map +1 -0
- package/src/compat/navigation-bus.d.ts +29 -0
- package/src/compat/navigation-bus.js +92 -0
- package/src/compat/navigation-bus.js.map +1 -0
- package/src/compat/realm-patches.d.ts +21 -0
- package/src/compat/realm-patches.js +573 -0
- package/src/compat/realm-patches.js.map +1 -0
- package/src/compat/register-worker.d.ts +45 -0
- package/src/compat/register-worker.js +57 -0
- package/src/compat/register-worker.js.map +1 -0
- package/src/compat/script-execution.d.ts +65 -0
- package/src/compat/script-execution.js +361 -0
- package/src/compat/script-execution.js.map +1 -0
- package/src/compat/service-worker.d.ts +22 -0
- package/src/compat/service-worker.js +104 -0
- package/src/compat/service-worker.js.map +1 -0
- package/src/config.d.ts +37 -0
- package/src/config.js +26 -0
- package/src/config.js.map +1 -0
- package/src/context/context-bus.d.ts +67 -0
- package/src/context/context-bus.js +117 -0
- package/src/context/context-bus.js.map +1 -0
- package/src/elements/fragment-slot.d.ts +39 -0
- package/src/elements/fragment-slot.js +281 -0
- package/src/elements/fragment-slot.js.map +1 -0
- package/src/env/create-env.d.ts +31 -0
- package/src/env/create-env.js +91 -0
- package/src/env/create-env.js.map +1 -0
- package/src/env/fragment-env.d.ts +56 -0
- package/src/env/fragment-env.js +14 -0
- package/src/env/fragment-env.js.map +1 -0
- package/src/errors.d.ts +21 -0
- package/src/errors.js +21 -0
- package/src/errors.js.map +1 -0
- package/src/index.d.ts +36 -0
- package/src/index.js +40 -0
- package/src/index.js.map +1 -0
- package/src/protocol.d.ts +38 -0
- package/src/protocol.js +45 -0
- package/src/protocol.js.map +1 -0
- package/src/realm/realm-manager.d.ts +60 -0
- package/src/realm/realm-manager.js +296 -0
- package/src/realm/realm-manager.js.map +1 -0
- package/src/utils/assert.d.ts +7 -0
- package/src/utils/assert.js +10 -0
- package/src/utils/assert.js.map +1 -0
- package/src/utils/selector-helpers.d.ts +10 -0
- package/src/utils/selector-helpers.js +13 -0
- package/src/utils/selector-helpers.js.map +1 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import { BraidError } from '../errors.js';
|
|
2
|
+
import { isDevMode } from '../config.js';
|
|
3
|
+
import { BRAID_ADAPTER_META, BRAID_ADAPTER_OPTIONS_META, BRAID_PROTOCOL_META, BRAID_PROTOCOL_VERSION, braidFragmentUrl, braidRealmUrl, } from '../protocol.js';
|
|
4
|
+
export async function createRealm(kind, init) {
|
|
5
|
+
switch (kind) {
|
|
6
|
+
case 'compat-http':
|
|
7
|
+
return createCompatHttpRealm(init);
|
|
8
|
+
case 'contract-blob':
|
|
9
|
+
return createContractBlobRealm(init);
|
|
10
|
+
case 'sandbox':
|
|
11
|
+
throw new BraidError('the sandbox realm kind (untrusted tier) is not available in this build', {
|
|
12
|
+
fragmentId: init.fragmentId,
|
|
13
|
+
stage: 'realm-boot',
|
|
14
|
+
fixHint: 'this build ships the trusted tier only — trusted realms are namespace isolation, not a security boundary',
|
|
15
|
+
});
|
|
16
|
+
default:
|
|
17
|
+
throw new BraidError(`unknown realm kind "${kind}"`, {
|
|
18
|
+
fragmentId: init.fragmentId,
|
|
19
|
+
stage: 'realm-boot',
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Creates a contract-mode realm from a `blob:` URL the runtime authors itself.
|
|
25
|
+
*
|
|
26
|
+
* Booting from a blob costs no network round trip, needs no gateway stub, and — because the
|
|
27
|
+
* realm never navigates — has **zero interaction with the joint session history**, which
|
|
28
|
+
* eliminates the whole class of back/forward corruption that http-booted realms have to work
|
|
29
|
+
* around. The realm document carries the fragment's `<base>` (so relative URLs resolve into the
|
|
30
|
+
* fragment's namespace) and the fragment's own import map.
|
|
31
|
+
*
|
|
32
|
+
* Contract-mode code never reads realm globals — it receives `env.location`/`env.document` — so
|
|
33
|
+
* the realm has no illusion to maintain and needs no patches. That is exactly why blob realms
|
|
34
|
+
* are safe here and forbidden in compat mode, where `history.replaceState` must be able to
|
|
35
|
+
* rewrite the realm's URL to the fragment's route (which a blob document cannot do).
|
|
36
|
+
*/
|
|
37
|
+
async function createContractBlobRealm(init) {
|
|
38
|
+
const { fragmentId, importMap } = init;
|
|
39
|
+
// The base href must be absolute: a blob: URL has an opaque path, so a root-relative href
|
|
40
|
+
// has nothing meaningful to resolve against.
|
|
41
|
+
const baseHref = new URL(braidFragmentUrl(fragmentId, '/'), location.origin).href;
|
|
42
|
+
const realmDocumentHtml = `<!doctype html><meta charset="utf-8"><title>Braid realm: ${escapeHtml(fragmentId)}</title>` +
|
|
43
|
+
`<meta name="${BRAID_PROTOCOL_META}" content="${BRAID_PROTOCOL_VERSION}">` +
|
|
44
|
+
`<base href="${escapeHtml(baseHref)}">` +
|
|
45
|
+
(importMap ? `<script type="importmap">${JSON.stringify(importMap)}</script>` : '');
|
|
46
|
+
const blobUrl = URL.createObjectURL(new Blob([realmDocumentHtml], { type: 'text/html' }));
|
|
47
|
+
const iframe = document.createElement('iframe');
|
|
48
|
+
iframe.hidden = true;
|
|
49
|
+
iframe.setAttribute('aria-hidden', 'true');
|
|
50
|
+
iframe.src = blobUrl;
|
|
51
|
+
iframe.name = `braid:${fragmentId}`;
|
|
52
|
+
const { promise: loaded, resolve: resolveLoaded, reject: rejectLoaded } = Promise.withResolvers();
|
|
53
|
+
iframe.addEventListener('load', () => resolveLoaded(), { once: true });
|
|
54
|
+
iframe.addEventListener('error', () => rejectLoaded(new BraidError('the contract realm document failed to load', {
|
|
55
|
+
fragmentId,
|
|
56
|
+
stage: 'realm-boot',
|
|
57
|
+
fixHint: `allow blob: in the host page's frame-src content security policy`,
|
|
58
|
+
})), { once: true });
|
|
59
|
+
document.body.appendChild(iframe);
|
|
60
|
+
try {
|
|
61
|
+
await loaded;
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
// the document has been created from it; the URL itself is no longer needed
|
|
65
|
+
URL.revokeObjectURL(blobUrl);
|
|
66
|
+
}
|
|
67
|
+
const realmWindow = iframe.contentWindow;
|
|
68
|
+
const realmDocument = iframe.contentDocument;
|
|
69
|
+
if (!realmWindow || !realmDocument) {
|
|
70
|
+
throw new BraidError('the contract realm is not same-origin with the host page', {
|
|
71
|
+
fragmentId,
|
|
72
|
+
stage: 'realm-boot',
|
|
73
|
+
fixHint: `allow blob: in the host page's frame-src content security policy`,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
const handle = createRealmHandle('contract-blob', iframe, realmWindow, realmDocument, null, {}, init);
|
|
77
|
+
if (isDevMode()) {
|
|
78
|
+
installContractRealmGuidance(realmDocument, fragmentId);
|
|
79
|
+
}
|
|
80
|
+
if (isDevMode()) {
|
|
81
|
+
console.debug(`[braid:${fragmentId}] contract-blob realm ready`, { baseHref });
|
|
82
|
+
}
|
|
83
|
+
init.signal.addEventListener('abort', () => handle.dispose(), { once: true });
|
|
84
|
+
return handle;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Reads the adapter's manifest options off the realm stub.
|
|
88
|
+
*
|
|
89
|
+
* Malformed JSON is a gateway bug rather than something an app can fix, so it warns and yields
|
|
90
|
+
* nothing instead of failing the boot — an adapter that needs an option reports its own absence
|
|
91
|
+
* with a far more useful message than a parse error would.
|
|
92
|
+
*/
|
|
93
|
+
function readAdapterOptions(realmDocument, fragmentId) {
|
|
94
|
+
const raw = realmDocument
|
|
95
|
+
.querySelector(`meta[name="${BRAID_ADAPTER_OPTIONS_META}"]`)
|
|
96
|
+
?.getAttribute('content');
|
|
97
|
+
if (!raw)
|
|
98
|
+
return {};
|
|
99
|
+
try {
|
|
100
|
+
const parsed = JSON.parse(raw);
|
|
101
|
+
return parsed && typeof parsed === 'object' ? parsed : {};
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
console.warn(`[braid:${fragmentId}] the gateway sent unparsable adapter options; ignoring them`);
|
|
105
|
+
return {};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Builds the shared part of a realm handle: module evaluation and disposal.
|
|
110
|
+
*
|
|
111
|
+
* Module evaluation injects a module script built with the realm's *native* `createElement` and
|
|
112
|
+
* appended to the realm's own body — a script created in another document does not execute, and
|
|
113
|
+
* a script cloned from a parser-created one carries the "already started" flag and never runs.
|
|
114
|
+
*/
|
|
115
|
+
function createRealmHandle(kind, iframe, realmWindow, realmDocument, manifestAdapter, adapterOptions, init) {
|
|
116
|
+
// captured before any facade or dev guidance is spliced into the document's prototype chain
|
|
117
|
+
const nativeCreateElement = Document.prototype.createElement.bind(realmDocument);
|
|
118
|
+
const realmBody = realmDocument.body;
|
|
119
|
+
let evaluationCounter = 0;
|
|
120
|
+
async function evaluateModule(source) {
|
|
121
|
+
const callbackName = `__braidModuleDone${evaluationCounter++}__`;
|
|
122
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
123
|
+
Object.defineProperty(realmWindow, callbackName, {
|
|
124
|
+
configurable: true,
|
|
125
|
+
value: () => resolve(true),
|
|
126
|
+
});
|
|
127
|
+
const script = nativeCreateElement('script');
|
|
128
|
+
script.type = 'module';
|
|
129
|
+
// import declarations are hoisted, so appending the completion call after the fragment's
|
|
130
|
+
// own source is valid regardless of what the source imports
|
|
131
|
+
script.textContent = `${source}\n;window.${callbackName}?.();`;
|
|
132
|
+
const onError = (event) => reject(new BraidError(`module evaluation failed in the fragment's realm: ${event.message}`, {
|
|
133
|
+
fragmentId: init.fragmentId,
|
|
134
|
+
stage: 'adapter-mount',
|
|
135
|
+
cause: event.error,
|
|
136
|
+
}));
|
|
137
|
+
realmWindow.addEventListener('error', onError, { once: true });
|
|
138
|
+
script.addEventListener('error', () => reject(new BraidError('a module script failed to load in the fragment realm', {
|
|
139
|
+
fragmentId: init.fragmentId,
|
|
140
|
+
stage: 'adapter-mount',
|
|
141
|
+
fixHint: 'check that the module url resolves inside the fragment namespace',
|
|
142
|
+
})));
|
|
143
|
+
realmBody.appendChild(script);
|
|
144
|
+
try {
|
|
145
|
+
return await promise;
|
|
146
|
+
}
|
|
147
|
+
finally {
|
|
148
|
+
realmWindow.removeEventListener('error', onError);
|
|
149
|
+
Reflect.deleteProperty(realmWindow, callbackName);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
kind,
|
|
154
|
+
fragmentId: init.fragmentId,
|
|
155
|
+
window: realmWindow,
|
|
156
|
+
document: realmDocument,
|
|
157
|
+
manifestAdapter,
|
|
158
|
+
adapterOptions,
|
|
159
|
+
evaluateModule,
|
|
160
|
+
async evaluate(entryUrl) {
|
|
161
|
+
// resolved against the realm's <base>, so it lands in the fragment's namespace
|
|
162
|
+
await evaluateModule(`import ${JSON.stringify(new URL(entryUrl, realmDocument.baseURI).href)};`);
|
|
163
|
+
},
|
|
164
|
+
dispose() {
|
|
165
|
+
iframe.remove();
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Dev-only guidance for contract realms: warns once when fragment code reads
|
|
171
|
+
* the realm's `document` instead of the `env` it was handed, and points at the contract.
|
|
172
|
+
*
|
|
173
|
+
* Known limitation, verified against the platform: `window.location` and `document.location`
|
|
174
|
+
* are `[LegacyUnforgeable]` — own, non-configurable properties that cannot be intercepted in
|
|
175
|
+
* any realm, ours included. So a fragment reaching for `location` gets the blob URL with no
|
|
176
|
+
* warning. This is the same platform rule that makes blob realms unable to fake an http URL,
|
|
177
|
+
* and it is why compat mode keeps http realms.
|
|
178
|
+
*/
|
|
179
|
+
function installContractRealmGuidance(realmDocument, fragmentId) {
|
|
180
|
+
const originalPrototype = Object.getPrototypeOf(realmDocument);
|
|
181
|
+
let warned = false;
|
|
182
|
+
const guidanceProxy = new Proxy(originalPrototype, {
|
|
183
|
+
get(target, property, receiver) {
|
|
184
|
+
if (!warned && typeof property === 'string' && property !== 'location') {
|
|
185
|
+
warned = true;
|
|
186
|
+
console.warn(`[braid:${fragmentId}] a contract-mode fragment read 'document.${property}' from its realm.\n` +
|
|
187
|
+
`Realm globals are explicitly out of contract: use the env your adapter received ` +
|
|
188
|
+
`(env.document, env.root, env.location) so the fragment keeps working when the isolation backend changes.`);
|
|
189
|
+
}
|
|
190
|
+
return Reflect.get(target, property, receiver);
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
Object.setPrototypeOf(realmDocument, guidanceProxy);
|
|
194
|
+
}
|
|
195
|
+
function escapeHtml(value) {
|
|
196
|
+
return value
|
|
197
|
+
.replaceAll('&', '&')
|
|
198
|
+
.replaceAll('<', '<')
|
|
199
|
+
.replaceAll('>', '>')
|
|
200
|
+
.replaceAll('"', '"');
|
|
201
|
+
}
|
|
202
|
+
async function createCompatHttpRealm(init) {
|
|
203
|
+
const { fragmentId, routeUrl, bound } = init;
|
|
204
|
+
const routeSrcUrl = new URL(routeUrl, document.baseURI);
|
|
205
|
+
if (routeSrcUrl.origin !== location.origin) {
|
|
206
|
+
throw new BraidError(`route url "${routeUrl}" is not same-origin with the host page`, {
|
|
207
|
+
fragmentId,
|
|
208
|
+
stage: 'realm-boot',
|
|
209
|
+
fixHint: 'compat fragments are served through the gateway on the host origin; use a path, not a cross-origin url',
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Create the iframe we'll load the fragment's JS context into, hidden from the viewport.
|
|
214
|
+
* The src must be set before the element is inserted to avoid double loads (and, in Firefox,
|
|
215
|
+
* spurious history records for iframes that get their src one task after insertion).
|
|
216
|
+
*/
|
|
217
|
+
const iframe = document.createElement('iframe');
|
|
218
|
+
iframe.hidden = true;
|
|
219
|
+
// the realm stub has its own namespace, so the fragment's asset URLs carry no header variance
|
|
220
|
+
iframe.src = braidRealmUrl(fragmentId, routeSrcUrl.pathname, routeSrcUrl.search);
|
|
221
|
+
iframe.name = `braid:${fragmentId}`;
|
|
222
|
+
const { promise: loaded, resolve: resolveLoaded, reject: rejectLoaded } = Promise.withResolvers();
|
|
223
|
+
let alreadyLoaded = false;
|
|
224
|
+
let pendingHardNavigationHref = null;
|
|
225
|
+
iframe.addEventListener('load', () => {
|
|
226
|
+
if (alreadyLoaded) {
|
|
227
|
+
// iframe reload detected: the fragment app attempted to reload or hard-navigate.
|
|
228
|
+
if (bound) {
|
|
229
|
+
// Workaround for a Safari (v26) bfcache bug: after a hard navigation away and a
|
|
230
|
+
// back-button return, Safari recreates the iframe with the old src but feeds it the
|
|
231
|
+
// new document. Intercept the first reload, park the target href, restore the
|
|
232
|
+
// host's location into the iframe, then complete the hard navigation on the host.
|
|
233
|
+
if (pendingHardNavigationHref) {
|
|
234
|
+
location.href = pendingHardNavigationHref;
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
pendingHardNavigationHref = iframe.contentWindow.location.href;
|
|
238
|
+
iframe.contentWindow.location.href = location.href;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
console.warn(`[braid:${fragmentId}] unbound fragment reload detected — fragment content is stale`);
|
|
243
|
+
}
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
alreadyLoaded = true;
|
|
247
|
+
try {
|
|
248
|
+
verifyRealmStub(iframe, fragmentId);
|
|
249
|
+
// Restore the fragment's route-url illusion: the iframe was loaded from the gateway
|
|
250
|
+
// namespace, but the fragment's JS context must observe the route url as its location.
|
|
251
|
+
// The stub's <base> element is unaffected by replaceState and keeps relative url
|
|
252
|
+
// resolution inside the namespace.
|
|
253
|
+
iframe.contentWindow.history.replaceState(null, '', routeSrcUrl.pathname + routeSrcUrl.search);
|
|
254
|
+
resolveLoaded();
|
|
255
|
+
}
|
|
256
|
+
catch (error) {
|
|
257
|
+
rejectLoaded(error);
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
document.body.appendChild(iframe);
|
|
261
|
+
await loaded;
|
|
262
|
+
if (isDevMode()) {
|
|
263
|
+
console.debug(`[braid:${fragmentId}] compat-http realm ready`, { src: iframe.src });
|
|
264
|
+
}
|
|
265
|
+
const handle = createRealmHandle('compat-http', iframe, iframe.contentWindow, iframe.contentDocument, iframe.contentDocument.querySelector(`meta[name="${BRAID_ADAPTER_META}"]`)?.getAttribute('content') ?? null, readAdapterOptions(iframe.contentDocument, fragmentId), init);
|
|
266
|
+
init.signal.addEventListener('abort', () => handle.dispose(), { once: true });
|
|
267
|
+
return handle;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Verifies the loaded iframe document is the gateway's realm stub for this protocol version.
|
|
271
|
+
* This replaces title-check heuristics with explicit version negotiation: mismatches and
|
|
272
|
+
* misconfigurations produce named errors with the likely fix.
|
|
273
|
+
*/
|
|
274
|
+
function verifyRealmStub(iframe, fragmentId) {
|
|
275
|
+
const stubDocument = iframe.contentDocument;
|
|
276
|
+
if (!stubDocument) {
|
|
277
|
+
throw new BraidError(`the realm document for "${iframe.src}" is not accessible`, {
|
|
278
|
+
fragmentId,
|
|
279
|
+
stage: 'realm-boot',
|
|
280
|
+
fixHint: 'ensure the gateway response is not delivered with "X-Frame-Options: deny" and is same-origin with the host page',
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
const protocol = stubDocument.querySelector(`meta[name="${BRAID_PROTOCOL_META}"]`)?.getAttribute('content');
|
|
284
|
+
if (protocol !== BRAID_PROTOCOL_VERSION) {
|
|
285
|
+
throw new BraidError(protocol
|
|
286
|
+
? `gateway speaks braid protocol "${protocol}" but this client speaks "${BRAID_PROTOCOL_VERSION}"`
|
|
287
|
+
: `the document loaded from "${iframe.src}" is not a braid realm stub`, {
|
|
288
|
+
fragmentId,
|
|
289
|
+
stage: 'realm-boot',
|
|
290
|
+
fixHint: protocol
|
|
291
|
+
? 'upgrade @braidlabs/core and @braidlabs/gateway to the same package version'
|
|
292
|
+
: `ensure the braid gateway is mounted in front of this app and has a manifest registered for fragment id "${fragmentId}"`,
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
//# sourceMappingURL=realm-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realm-manager.js","sourceRoot":"","sources":["../../../../../libs/core/src/realm/realm-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A generic assertion function.
|
|
3
|
+
*
|
|
4
|
+
* Typescript doesn't consider `console.assert` to be an assertion function, hence this wrapper.
|
|
5
|
+
* https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions
|
|
6
|
+
*/
|
|
7
|
+
export declare function assert(value: boolean, message: string): asserts value;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A generic assertion function.
|
|
3
|
+
*
|
|
4
|
+
* Typescript doesn't consider `console.assert` to be an assertion function, hence this wrapper.
|
|
5
|
+
* https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions
|
|
6
|
+
*/
|
|
7
|
+
export function assert(value, message) {
|
|
8
|
+
console.assert(value, message);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=assert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assert.js","sourceRoot":"","sources":["../../../../../libs/core/src/utils/assert.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAC,KAAc,EAAE,OAAe;IACpD,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* For CSS selectors that contain html, head, and body tag names, rewrite the selector with the
|
|
3
|
+
* braid-* prefix (the custom elements standing in for those singletons inside a fragment's DOM).
|
|
4
|
+
*
|
|
5
|
+
* Breakdown of the regex:
|
|
6
|
+
* (?<=^|[\s>+~,(]) - lookbehind to only match when preceded by start of string, whitespace and combinators
|
|
7
|
+
* \b(body|head|html)\b - match body|head|html exactly, but only at word boundaries
|
|
8
|
+
* (?=[\s>+~),:.#[\]]|$) - lookahead to only match when followed by end of string or combinators
|
|
9
|
+
*/
|
|
10
|
+
export declare const rewriteQuerySelector: (selector: string) => string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* For CSS selectors that contain html, head, and body tag names, rewrite the selector with the
|
|
3
|
+
* braid-* prefix (the custom elements standing in for those singletons inside a fragment's DOM).
|
|
4
|
+
*
|
|
5
|
+
* Breakdown of the regex:
|
|
6
|
+
* (?<=^|[\s>+~,(]) - lookbehind to only match when preceded by start of string, whitespace and combinators
|
|
7
|
+
* \b(body|head|html)\b - match body|head|html exactly, but only at word boundaries
|
|
8
|
+
* (?=[\s>+~),:.#[\]]|$) - lookahead to only match when followed by end of string or combinators
|
|
9
|
+
*/
|
|
10
|
+
export const rewriteQuerySelector = (selector) => selector
|
|
11
|
+
?.toString()
|
|
12
|
+
.replace(/(?<=^|[\s>+~,(])\b(body|head|html)\b(?=[\s>+~),:.#[\]]|$)/gi, (match) => `braid-${match.toLowerCase()}`) ?? selector;
|
|
13
|
+
//# sourceMappingURL=selector-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selector-helpers.js","sourceRoot":"","sources":["../../../../../libs/core/src/utils/selector-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,QAAgB,EAAE,EAAE,CACvD,QAAQ;IACN,EAAE,QAAQ,EAAE;KACX,OAAO,CACN,6DAA6D,EAC7D,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,KAAK,CAAC,WAAW,EAAE,EAAE,CAC1C,IAAI,QAAQ,CAAC"}
|