@bakery-framework/core 1.2.3 → 2.0.0-alpha.11
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/package.json +2 -2
- package/src/cache/shared-db.ts +7 -9
- package/src/client/globals.d.ts +1 -1
- package/src/client/utils.ts +41 -9
- package/src/compiler/compiler.ts +458 -39
- package/src/compiler/prompt-tracker.ts +19 -2
- package/src/compiler/tsconfig-sync.ts +116 -45
- package/src/core/bakery.ts +11 -12
- package/src/core/context.ts +42 -8
- package/src/core/index.ts +18 -0
- package/src/core/init.ts +40 -31
- package/src/global.d.ts +24 -6
- package/src/handlers/assets/nm.ts +74 -15
- package/src/handlers/assets/static.ts +53 -10
- package/src/handlers/core/$base.ts +71 -8
- package/src/handlers/core/$dynamic.ts +21 -10
- package/src/handlers/core/$error.ts +10 -1
- package/src/handlers/core/$registry.ts +31 -2
- package/src/handlers/core/$routing.ts +82 -11
- package/src/handlers/routes/api.ts +2 -2
- package/src/handlers/routes/proxy.ts +2 -1
- package/src/logger/serve-log.ts +21 -0
- package/src/plugins/types.ts +7 -5
- package/src/router.ts +5 -5
- package/src/session.ts +0 -3
- package/src/shared.d.ts +7 -0
- package/src/types.d.ts +11 -0
- package/src/utils/fs.ts +29 -0
- package/src/utils/http/authorize.ts +136 -0
- package/src/utils/http/body.ts +2 -2
- package/src/utils/http/credential.ts +70 -0
- package/src/utils/http/dom.ts +73 -64
- package/src/utils/http/etag.ts +27 -0
- package/src/utils/http/html.ts +16 -5
- package/src/utils/http/index.ts +3 -0
- package/src/utils/http/url.ts +35 -0
- package/src/utils/isomorphic/misc.ts +16 -0
package/src/utils/http/html.ts
CHANGED
|
@@ -4,7 +4,18 @@ import { Try } from '../common/try'
|
|
|
4
4
|
import { DOMTools, headBodyCache } from './dom'
|
|
5
5
|
import { ETag } from './etag'
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Mark `res` as already carrying the head/body injects, so `injectIfHtml` —
|
|
9
|
+
* and therefore `processResponse`, which every response funnels through —
|
|
10
|
+
* hands it back untouched.
|
|
11
|
+
*
|
|
12
|
+
* Exported for the one caller that means "never", not "already":
|
|
13
|
+
* `DefaultErrorHandler` brands its production error page so the import map is
|
|
14
|
+
* not spliced into it. That map names every installed package — an inventory
|
|
15
|
+
* of the app's module layout — and the page carries no scripts for it (or the
|
|
16
|
+
* client bundle) to serve anyway.
|
|
17
|
+
*/
|
|
18
|
+
export function injectBrand(res: Response) {
|
|
8
19
|
return Object.defineProperty(res, '__injected__', {
|
|
9
20
|
value: true,
|
|
10
21
|
enumerable: false,
|
|
@@ -80,7 +91,7 @@ export const STREAM_THRESHOLD_BYTES = 64 * 1024
|
|
|
80
91
|
|
|
81
92
|
export async function injectIfHtml(
|
|
82
93
|
data: string | Response | Blob,
|
|
83
|
-
params?: MapOf<
|
|
94
|
+
params?: MapOf<unknown>,
|
|
84
95
|
injects?: HtmlInjects,
|
|
85
96
|
): Promise<Response | null> {
|
|
86
97
|
if (data instanceof Response && isInjected(data)) return data
|
|
@@ -127,7 +138,7 @@ export async function injectIfHtml(
|
|
|
127
138
|
* streamed path's fallback both come through here. */
|
|
128
139
|
function bufferedResponse(
|
|
129
140
|
content: string,
|
|
130
|
-
params: MapOf<
|
|
141
|
+
params: MapOf<unknown> | undefined,
|
|
131
142
|
injects: HtmlInjects | undefined,
|
|
132
143
|
responseInit: ResponseInit & { headers?: any },
|
|
133
144
|
): Response {
|
|
@@ -182,7 +193,7 @@ function getConfigInjects() {
|
|
|
182
193
|
* into a pull callback, where the AsyncLocalStorage host context that
|
|
183
194
|
* `getConfigInjects` and `DOMTools.importMap` read may no longer be live.
|
|
184
195
|
*/
|
|
185
|
-
function computeInjects(params: MapOf<
|
|
196
|
+
function computeInjects(params: MapOf<unknown>, injects: HtmlInjects) {
|
|
186
197
|
const configInjects = getConfigInjects()
|
|
187
198
|
const paramsStr = DOMTools.params(params)
|
|
188
199
|
|
|
@@ -235,7 +246,7 @@ function rewriteFontsUrls(html: string): string {
|
|
|
235
246
|
|
|
236
247
|
export function assembleHtml(
|
|
237
248
|
content: string,
|
|
238
|
-
params: MapOf<
|
|
249
|
+
params: MapOf<unknown> = {},
|
|
239
250
|
injects: HtmlInjects = {},
|
|
240
251
|
) {
|
|
241
252
|
const frags = computeInjects(params, injects)
|
package/src/utils/http/index.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
export * from './authorize'
|
|
1
2
|
export * from './body'
|
|
3
|
+
export * from './credential'
|
|
2
4
|
export * from './csrf'
|
|
3
5
|
export * from './dom'
|
|
4
6
|
export * from './escape'
|
|
@@ -7,3 +9,4 @@ export * from './html'
|
|
|
7
9
|
export * from './ip'
|
|
8
10
|
export * from './response'
|
|
9
11
|
export * from './sse'
|
|
12
|
+
export * from './url'
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The request's parsed URL, parsed at most once.
|
|
3
|
+
*
|
|
4
|
+
* Why memoize at all: `new URL` measures ~1.7µs, and the router, the body
|
|
5
|
+
* parser and the proxy handler all want the same parse of the same request —
|
|
6
|
+
* so the parse was hoisted into the server's `fetch` in `packages/cli/src/worker.ts`
|
|
7
|
+
* and shared.
|
|
8
|
+
*
|
|
9
|
+
* Why a `WeakMap` rather than the property it replaces. The memo used to be
|
|
10
|
+
* `(req as any).__parsedUrl`: two writers, six readers across three packages,
|
|
11
|
+
* every reader spelled `(req as any).__parsedUrl || new URL(req.url)` so that
|
|
12
|
+
* it silently re-parsed whenever the writer had not run first. That is a
|
|
13
|
+
* writer/reader ordering hazard with no way to observe it going wrong — a
|
|
14
|
+
* missed write costs microseconds, not correctness, so nothing ever fails.
|
|
15
|
+
* One function collapses both roles: there is no ordering left to get wrong,
|
|
16
|
+
* no `any` cast anywhere, and no writer to forget. The map also keeps the
|
|
17
|
+
* framework from mutating a `Request` object it does not own — a caller's
|
|
18
|
+
* `Request` goes in and comes back unchanged — and holds its keys weakly, so
|
|
19
|
+
* an entry dies with the request rather than needing eviction (convention 6).
|
|
20
|
+
*
|
|
21
|
+
* There is deliberately no setter. Nothing outside this module needs to say
|
|
22
|
+
* what a request's URL is; `req.url` already does.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
const cache = new WeakMap<Request, URL>()
|
|
26
|
+
|
|
27
|
+
/** The parsed `req.url`, cached per request. */
|
|
28
|
+
export function parsedUrl(req: Request): URL {
|
|
29
|
+
const cached = cache.get(req)
|
|
30
|
+
if (cached) return cached
|
|
31
|
+
|
|
32
|
+
const url = new URL(req.url)
|
|
33
|
+
cache.set(req, url)
|
|
34
|
+
return url
|
|
35
|
+
}
|
|
@@ -15,6 +15,22 @@ export function any<T = any>(value: any): T {
|
|
|
15
15
|
return value
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* A hex id of `length` characters, from `crypto.getRandomValues`.
|
|
20
|
+
*
|
|
21
|
+
* Isomorphic, and moving it here is what made it so: it lived in
|
|
22
|
+
* `client/utils.ts` as a browser global only, so the same call in a server
|
|
23
|
+
* block was a ReferenceError — reported from an app. `crypto` is a global in
|
|
24
|
+
* both runtimes; nothing here is browser-specific.
|
|
25
|
+
*/
|
|
26
|
+
export function randomId(length = 8) {
|
|
27
|
+
const arr = new Uint8Array(Math.ceil(length / 2))
|
|
28
|
+
crypto.getRandomValues(arr)
|
|
29
|
+
return Array.from(arr, dec => dec.toString(16).padStart(2, '0'))
|
|
30
|
+
.join('')
|
|
31
|
+
.slice(0, length)
|
|
32
|
+
}
|
|
33
|
+
|
|
18
34
|
export function repeat(n: number): number[]
|
|
19
35
|
export function repeat<T>(n: number, fn: (i: number) => T): T[]
|
|
20
36
|
export function repeat<T>(n: number, fn?: (i: number) => T): unknown[] {
|