@primate/core 0.3.4 → 0.4.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/lib/private/App.d.ts +5 -19
- package/lib/private/App.js +13 -75
- package/lib/private/Binder.d.ts +1 -3
- package/lib/private/Flags.d.ts +7 -0
- package/lib/private/Flags.js +7 -0
- package/lib/private/Module.d.ts +2 -2
- package/lib/private/backend/TAG.d.ts +1 -1
- package/lib/private/backend/TAG.js +1 -1
- package/lib/private/build/App.d.ts +34 -0
- package/lib/private/build/App.js +103 -0
- package/lib/private/build/client/index.d.ts +3 -0
- package/lib/private/build/client/index.js +95 -0
- package/lib/private/build/client/plugin/alias.d.ts +4 -0
- package/lib/private/build/client/plugin/alias.js +12 -0
- package/lib/private/build/client/plugin/entrypoint.d.ts +4 -0
- package/lib/private/build/client/plugin/entrypoint.js +15 -0
- package/lib/private/build/client/plugin/frontend.d.ts +4 -0
- package/lib/private/build/client/plugin/frontend.js +15 -0
- package/lib/private/build/client/plugin/server-stamp.d.ts +4 -0
- package/lib/private/build/client/plugin/server-stamp.js +14 -0
- package/lib/private/build/client/reload.d.ts +7 -0
- package/lib/private/build/client/reload.js +6 -0
- package/lib/private/{hook/build.d.ts → build/hook.d.ts} +2 -2
- package/lib/private/build/hook.js +49 -0
- package/lib/private/build/index.d.ts +4 -0
- package/lib/private/{build.js → build/index.js} +7 -5
- package/lib/private/build/server/index.d.ts +3 -0
- package/lib/private/build/server/index.js +90 -0
- package/lib/private/build/server/plugin/assets.d.ts +4 -0
- package/lib/private/build/server/plugin/assets.js +67 -0
- package/lib/private/build/server/plugin/config.d.ts +4 -0
- package/lib/private/build/server/plugin/config.js +43 -0
- package/lib/private/build/server/plugin/database-default.d.ts +4 -0
- package/lib/private/build/server/plugin/database-default.js +48 -0
- package/lib/private/build/server/plugin/frontend.d.ts +4 -0
- package/lib/private/build/server/plugin/frontend.js +21 -0
- package/lib/private/build/server/plugin/hot-reload.d.ts +4 -0
- package/lib/private/build/server/plugin/hot-reload.js +36 -0
- package/lib/private/build/server/plugin/native-addons.d.ts +4 -0
- package/lib/private/build/server/plugin/native-addons.js +55 -0
- package/lib/private/build/server/plugin/node-imports.d.ts +4 -0
- package/lib/private/build/server/plugin/node-imports.js +32 -0
- package/lib/private/build/server/plugin/requires.d.ts +4 -0
- package/lib/private/build/server/plugin/requires.js +30 -0
- package/lib/private/build/server/plugin/roots.d.ts +4 -0
- package/lib/private/build/server/plugin/roots.js +18 -0
- package/lib/private/build/server/plugin/route.d.ts +4 -0
- package/lib/private/build/server/plugin/route.js +56 -0
- package/lib/private/build/server/plugin/store-wrap.d.ts +4 -0
- package/lib/private/build/server/plugin/store-wrap.js +33 -0
- package/lib/private/build/server/plugin/store.d.ts +4 -0
- package/lib/private/build/server/plugin/store.js +47 -0
- package/lib/private/build/server/plugin/stores.d.ts +4 -0
- package/lib/private/build/server/plugin/stores.js +25 -0
- package/lib/private/build/server/plugin/view.d.ts +4 -0
- package/lib/private/build/server/plugin/view.js +64 -0
- package/lib/private/build/server/plugin/views.d.ts +4 -0
- package/lib/private/build/server/plugin/views.js +36 -0
- package/lib/private/build/server/plugin/virtual-pages.d.ts +4 -0
- package/lib/private/build/server/plugin/virtual-pages.js +41 -0
- package/lib/private/build/server/plugin/virtual-routes.d.ts +4 -0
- package/lib/private/build/server/plugin/virtual-routes.js +46 -0
- package/lib/private/build/server/plugin/wasm.d.ts +4 -0
- package/lib/private/build/server/plugin/wasm.js +36 -0
- package/lib/private/client/Data.d.ts +2 -0
- package/lib/private/client/app.js +4 -1
- package/lib/private/config/index.d.ts +0 -2
- package/lib/private/config/schema.d.ts +4 -6
- package/lib/private/config/schema.js +9 -19
- package/lib/private/database/Store.d.ts +4 -1
- package/lib/private/database/Store.js +8 -2
- package/lib/private/database/test.js +8 -8
- package/lib/private/frontend/Module.d.ts +4 -3
- package/lib/private/frontend/Module.js +47 -50
- package/lib/private/frontend/Publish.d.ts +1 -1
- package/lib/private/i18n/Module.d.ts +1 -1
- package/lib/private/i18n/Module.js +2 -2
- package/lib/private/location.d.ts +0 -6
- package/lib/private/location.js +0 -12
- package/lib/private/module/BuildHook.d.ts +1 -1
- package/lib/private/module/NextBuild.d.ts +1 -1
- package/lib/private/module/NextServe.d.ts +1 -1
- package/lib/private/paths.d.ts +5 -0
- package/lib/private/paths.js +30 -0
- package/lib/private/reducer.d.ts +2 -2
- package/lib/private/request/route.d.ts +1 -1
- package/lib/private/request/route.js +6 -8
- package/lib/private/response/ResponseFunction.d.ts +1 -1
- package/lib/private/response/binary.d.ts +1 -1
- package/lib/private/response/json.d.ts +1 -1
- package/lib/private/response/sse.d.ts +1 -1
- package/lib/private/response/text.d.ts +1 -1
- package/lib/private/response/view.d.ts +6 -9
- package/lib/private/response/view.js +12 -8
- package/lib/private/response.d.ts +1 -1
- package/lib/private/route/router.d.ts +3 -2
- package/lib/private/route/router.js +5 -4
- package/lib/private/{ServeApp.d.ts → serve/App.d.ts} +5 -22
- package/lib/private/{ServeApp.js → serve/App.js} +106 -35
- package/lib/private/{ServeInit.d.ts → serve/Init.d.ts} +16 -12
- package/lib/private/serve/Init.js +2 -0
- package/lib/private/{hook/serve.d.ts → serve/hook.d.ts} +2 -2
- package/lib/private/{hook/serve.js → serve/hook.js} +1 -1
- package/lib/private/serve/index.d.ts +5 -0
- package/lib/private/serve/index.js +6 -0
- package/lib/private/{builtin/DevModule.d.ts → serve/module/Dev.d.ts} +2 -2
- package/lib/private/{builtin/DevModule.js → serve/module/Dev.js} +4 -6
- package/lib/private/{builtin/HandleModule.d.ts → serve/module/Handle.d.ts} +2 -2
- package/lib/private/{builtin/HandleModule.js → serve/module/Handle.js} +2 -2
- package/lib/private/session/SessionModule.d.ts +3 -2
- package/lib/private/session/SessionModule.js +47 -24
- package/lib/private/session/index.d.ts +11 -8
- package/lib/private/session/index.js +5 -3
- package/lib/private/session/schema.d.ts +2 -4
- package/lib/private/session/schema.js +14 -16
- package/lib/private/target/Manager.js +5 -1
- package/lib/private/wasm/instantiate.js +2 -2
- package/lib/public/BuildApp.d.ts +1 -1
- package/lib/public/BuildApp.js +1 -1
- package/lib/public/Flags.d.ts +2 -0
- package/lib/public/Flags.js +2 -0
- package/lib/public/ServeApp.d.ts +1 -1
- package/lib/public/ServeApp.js +1 -1
- package/lib/public/build.d.ts +1 -1
- package/lib/public/build.js +1 -1
- package/lib/public/serve.d.ts +1 -1
- package/lib/public/serve.js +1 -1
- package/package.json +7 -7
- package/lib/private/BindingContext.d.ts +0 -3
- package/lib/private/BindingContext.js +0 -2
- package/lib/private/BuildApp.d.ts +0 -31
- package/lib/private/BuildApp.js +0 -130
- package/lib/private/Loader.d.ts +0 -17
- package/lib/private/Loader.js +0 -47
- package/lib/private/ServeInit.js +0 -2
- package/lib/private/build.d.ts +0 -4
- package/lib/private/config/config/app.d.ts +0 -3
- package/lib/private/config/config/app.js +0 -3
- package/lib/private/config/config/database/index.d.ts +0 -3
- package/lib/private/config/config/database/index.js +0 -3
- package/lib/private/config/config/session.d.ts +0 -3
- package/lib/private/config/config/session.js +0 -3
- package/lib/private/frontend/bundle-server.d.ts +0 -13
- package/lib/private/frontend/bundle-server.js +0 -48
- package/lib/private/hook/build.js +0 -260
- package/lib/private/serve.d.ts +0 -5
- package/lib/private/serve.js +0 -8
- package/lib/private/session/InMemoryManager.d.ts +0 -9
- package/lib/private/session/InMemoryManager.js +0 -23
- package/lib/private/session/Manager.d.ts +0 -9
- package/lib/private/session/Manager.js +0 -4
- package/lib/private/target/web.d.ts +0 -4
- package/lib/private/target/web.js +0 -58
- package/lib/public/Loader.d.ts +0 -2
- package/lib/public/Loader.js +0 -2
- package/lib/public/session/Manager.d.ts +0 -2
- package/lib/public/session/Manager.js +0 -2
|
@@ -4,12 +4,11 @@ import type ServerView from "#frontend/ServerView";
|
|
|
4
4
|
import type ViewOptions from "#frontend/ViewOptions";
|
|
5
5
|
import type ViewResponse from "#frontend/ViewResponse";
|
|
6
6
|
import type I18NConfig from "#i18n/Config";
|
|
7
|
-
import type Loader from "#Loader";
|
|
8
7
|
import RequestBag from "#request/RequestBag";
|
|
9
8
|
import RequestBody from "#request/RequestBody";
|
|
10
9
|
import type RequestFacade from "#request/RequestFacade";
|
|
11
10
|
import type RouteHandler from "#route/Handler";
|
|
12
|
-
import type ServeInit from "#
|
|
11
|
+
import type ServeInit from "#serve/Init";
|
|
13
12
|
import FileRouter from "@rcompat/fs/FileRouter";
|
|
14
13
|
import type Actions from "@rcompat/http/Actions";
|
|
15
14
|
import type Dict from "@rcompat/type/Dict";
|
|
@@ -26,20 +25,13 @@ export default class ServeApp extends App {
|
|
|
26
25
|
#private;
|
|
27
26
|
constructor(rootfile: string, init: ServeInit);
|
|
28
27
|
get secure(): boolean;
|
|
29
|
-
loader<T extends Loader>(): T;
|
|
30
|
-
serve(pathname: string): Promise<Response | undefined>;
|
|
31
28
|
get assets(): Asset[];
|
|
32
|
-
get modules(): import("
|
|
29
|
+
get modules(): import("../Module.js").default[];
|
|
33
30
|
get url(): string;
|
|
34
31
|
get router(): FileRouter;
|
|
35
32
|
get frontends(): {
|
|
36
33
|
[x: string]: ViewResponse | undefined;
|
|
37
34
|
};
|
|
38
|
-
get files(): {
|
|
39
|
-
routes: [string, {
|
|
40
|
-
default: any;
|
|
41
|
-
}][];
|
|
42
|
-
};
|
|
43
35
|
get stores(): Dict;
|
|
44
36
|
get i18n(): I18NConfig | undefined;
|
|
45
37
|
loadView<T = ServerView>(name: string): T;
|
|
@@ -47,7 +39,6 @@ export default class ServeApp extends App {
|
|
|
47
39
|
"Content-Security-Policy"?: string | undefined;
|
|
48
40
|
};
|
|
49
41
|
render(content: Omit<FullViewOptions, keyof ResponseInit>): string;
|
|
50
|
-
page(page?: string): string;
|
|
51
42
|
body_length(body: BodyInit | null): number;
|
|
52
43
|
respond(body: BodyInit | null, init?: ResponseInit): Response;
|
|
53
44
|
view(options: FullViewOptions): Response;
|
|
@@ -55,6 +46,8 @@ export default class ServeApp extends App {
|
|
|
55
46
|
publish({ code, inline, src, type }: PublishOptions): Promise<void>;
|
|
56
47
|
create_csp(): void;
|
|
57
48
|
register(extension: string, viewFunction: ViewResponse): void;
|
|
49
|
+
page(name?: string): string;
|
|
50
|
+
serveAsset(pathname: string): Promise<Response | undefined>;
|
|
58
51
|
start(): Promise<void>;
|
|
59
52
|
stop(): void;
|
|
60
53
|
upgrade(request: Request, actions: Actions): null;
|
|
@@ -76,16 +69,6 @@ export default class ServeApp extends App {
|
|
|
76
69
|
url: URL;
|
|
77
70
|
};
|
|
78
71
|
} | undefined>;
|
|
79
|
-
get session(): {
|
|
80
|
-
cookie: {
|
|
81
|
-
httpOnly: boolean;
|
|
82
|
-
name: string;
|
|
83
|
-
path: string;
|
|
84
|
-
sameSite: "Lax" | "None" | "Strict";
|
|
85
|
-
};
|
|
86
|
-
manager: import("./session/Manager.js").default<unknown>;
|
|
87
|
-
schema: import("@rcompat/type/Schema").default<unknown> | undefined;
|
|
88
|
-
};
|
|
89
72
|
}
|
|
90
73
|
export {};
|
|
91
|
-
//# sourceMappingURL=
|
|
74
|
+
//# sourceMappingURL=App.d.ts.map
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import App from "#App";
|
|
2
|
-
import DevModule from "#builtin/DevModule";
|
|
3
|
-
import HandleModule from "#builtin/HandleModule";
|
|
4
2
|
import fail from "#fail";
|
|
5
3
|
import hash from "#hash";
|
|
6
4
|
import I18NModule from "#i18n/Module";
|
|
@@ -11,11 +9,14 @@ import parse from "#request/parse";
|
|
|
11
9
|
import RequestBag from "#request/RequestBag";
|
|
12
10
|
import RequestBody from "#request/RequestBody";
|
|
13
11
|
import router from "#route/router";
|
|
12
|
+
import DevModule from "#serve/module/Dev";
|
|
13
|
+
import HandleModule from "#serve/module/Handle";
|
|
14
14
|
import SessionModule from "#session/SessionModule";
|
|
15
15
|
import tags from "#tags";
|
|
16
16
|
import is from "@rcompat/assert/is";
|
|
17
17
|
import FileRef from "@rcompat/fs/FileRef";
|
|
18
18
|
import FileRouter from "@rcompat/fs/FileRouter";
|
|
19
|
+
import resolve from "@rcompat/http/mime/extension/resolve";
|
|
19
20
|
import TEXT_HTML from "@rcompat/http/mime/text/html";
|
|
20
21
|
import serve from "@rcompat/http/serve";
|
|
21
22
|
import Status from "@rcompat/http/Status";
|
|
@@ -58,16 +59,25 @@ export default class ServeApp extends App {
|
|
|
58
59
|
#views;
|
|
59
60
|
#csp = {};
|
|
60
61
|
#assets = [];
|
|
62
|
+
#serve_assets;
|
|
63
|
+
#pages;
|
|
61
64
|
#stores;
|
|
62
65
|
#frontends = {};
|
|
63
66
|
#router;
|
|
64
67
|
#builtins;
|
|
65
68
|
#i18n_config;
|
|
66
69
|
constructor(rootfile, init) {
|
|
67
|
-
|
|
70
|
+
const dir = new FileRef(rootfile).directory;
|
|
71
|
+
super(dir, init.config, {
|
|
72
|
+
mode: init.mode,
|
|
73
|
+
target: init.target,
|
|
74
|
+
dir: dir.path,
|
|
75
|
+
});
|
|
68
76
|
this.#init = init;
|
|
69
77
|
this.#views = Object.fromEntries(init.views ?? []);
|
|
70
78
|
this.#stores = Object.fromEntries((init.stores?.map(([k, s]) => [k, s.default])) ?? []);
|
|
79
|
+
this.#serve_assets = init.assets;
|
|
80
|
+
this.#pages = init.pages;
|
|
71
81
|
const http = this.#init.config.http;
|
|
72
82
|
this.#i18n_config = init.i18n_config;
|
|
73
83
|
this.set(s_http, {
|
|
@@ -85,11 +95,11 @@ export default class ServeApp extends App {
|
|
|
85
95
|
guard: { recursive: true },
|
|
86
96
|
layout: { recursive: true },
|
|
87
97
|
},
|
|
88
|
-
}, init.
|
|
98
|
+
}, init.routes.map(s => s[0]));
|
|
89
99
|
this.#builtins = {
|
|
90
100
|
dev: init.mode === "development" ? new DevModule(this) : undefined,
|
|
91
101
|
handle: new HandleModule(this),
|
|
92
|
-
session: new SessionModule(this),
|
|
102
|
+
session: init.session_config ? new SessionModule(this.secure, init.session_config) : undefined,
|
|
93
103
|
i18n: init.i18n_config ? new I18NModule(init.i18n_config) : undefined,
|
|
94
104
|
};
|
|
95
105
|
}
|
|
@@ -98,12 +108,6 @@ export default class ServeApp extends App {
|
|
|
98
108
|
const ssl = this.config("http.ssl");
|
|
99
109
|
return ssl.key !== undefined && ssl.cert !== undefined;
|
|
100
110
|
}
|
|
101
|
-
loader() {
|
|
102
|
-
return this.#init.loader;
|
|
103
|
-
}
|
|
104
|
-
serve(pathname) {
|
|
105
|
-
return this.loader().serve(pathname);
|
|
106
|
-
}
|
|
107
111
|
get assets() {
|
|
108
112
|
return this.#assets;
|
|
109
113
|
}
|
|
@@ -122,9 +126,6 @@ export default class ServeApp extends App {
|
|
|
122
126
|
get frontends() {
|
|
123
127
|
return { ...this.#frontends };
|
|
124
128
|
}
|
|
125
|
-
get files() {
|
|
126
|
-
return this.#init.files;
|
|
127
|
-
}
|
|
128
129
|
get stores() {
|
|
129
130
|
return this.#stores;
|
|
130
131
|
}
|
|
@@ -132,13 +133,17 @@ export default class ServeApp extends App {
|
|
|
132
133
|
return this.#i18n_config;
|
|
133
134
|
}
|
|
134
135
|
loadView(name) {
|
|
135
|
-
const f = new FileRef(name);
|
|
136
|
-
const
|
|
136
|
+
const f = new FileRef(name).path;
|
|
137
|
+
const frontends = Object.keys(this.frontends);
|
|
138
|
+
const extension = frontends.find(frontend => f.endsWith(frontend));
|
|
139
|
+
const base = extension === undefined ? name : f.slice(0, -extension.length);
|
|
137
140
|
const view = this.#views[base];
|
|
138
|
-
if (view === undefined)
|
|
139
|
-
throw fail("
|
|
141
|
+
if (view === undefined)
|
|
142
|
+
throw fail("no view {0}", name);
|
|
143
|
+
if (view.default === undefined) {
|
|
144
|
+
throw fail("view {0} must export a default component", name);
|
|
140
145
|
}
|
|
141
|
-
return
|
|
146
|
+
return view.default;
|
|
142
147
|
}
|
|
143
148
|
;
|
|
144
149
|
headers(csp = {}) {
|
|
@@ -164,9 +169,6 @@ export default class ServeApp extends App {
|
|
|
164
169
|
.replace("%body%", body)
|
|
165
170
|
.replace("%head%", render_head(this.#assets, head));
|
|
166
171
|
}
|
|
167
|
-
page(page) {
|
|
168
|
-
return this.loader().page(page);
|
|
169
|
-
}
|
|
170
172
|
body_length(body) {
|
|
171
173
|
return typeof body === "string" ? utf8ByteLength(body) : 0;
|
|
172
174
|
}
|
|
@@ -224,15 +226,88 @@ export default class ServeApp extends App {
|
|
|
224
226
|
this.#frontends[extension] = viewFunction;
|
|
225
227
|
}
|
|
226
228
|
;
|
|
229
|
+
page(name) {
|
|
230
|
+
const page_name = name ?? location.app_html;
|
|
231
|
+
return this.#pages[page_name];
|
|
232
|
+
}
|
|
233
|
+
async #try_serve(file) {
|
|
234
|
+
if (await file.exists() && await file.isFile()) {
|
|
235
|
+
return new Response(file.stream(), {
|
|
236
|
+
headers: {
|
|
237
|
+
"Content-Type": resolve(file.name),
|
|
238
|
+
"Content-Length": String(await file.byteLength()),
|
|
239
|
+
},
|
|
240
|
+
status: Status.OK,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
async serveAsset(pathname) {
|
|
245
|
+
const static_root = this.config("http.static.root");
|
|
246
|
+
if (!pathname.startsWith(static_root))
|
|
247
|
+
return undefined;
|
|
248
|
+
if (this.mode === "development") {
|
|
249
|
+
const client_asset = this.root.join(location.client, pathname);
|
|
250
|
+
const client_response = await this.#try_serve(client_asset);
|
|
251
|
+
if (client_response !== undefined)
|
|
252
|
+
return client_response;
|
|
253
|
+
const static_asset = this.root.join("..", location.static, pathname);
|
|
254
|
+
const static_response = await this.#try_serve(static_asset);
|
|
255
|
+
if (static_response !== undefined)
|
|
256
|
+
return static_response;
|
|
257
|
+
return undefined;
|
|
258
|
+
}
|
|
259
|
+
const asset = this.#serve_assets.client[pathname] ??
|
|
260
|
+
this.#serve_assets.static[pathname];
|
|
261
|
+
if (asset) {
|
|
262
|
+
const binary = atob(asset.data);
|
|
263
|
+
const bytes = new Uint8Array(binary.length);
|
|
264
|
+
for (let i = 0; i < binary.length; i++) {
|
|
265
|
+
bytes[i] = binary.charCodeAt(i);
|
|
266
|
+
}
|
|
267
|
+
return new Response(bytes, {
|
|
268
|
+
headers: {
|
|
269
|
+
"Content-Type": asset.mime,
|
|
270
|
+
"Content-Length": String(bytes.length),
|
|
271
|
+
},
|
|
272
|
+
status: Status.OK,
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
return undefined;
|
|
276
|
+
}
|
|
227
277
|
async start() {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
278
|
+
if (this.mode === "production") {
|
|
279
|
+
this.#assets = await Promise.all(Object.entries(this.#serve_assets.client)
|
|
280
|
+
.filter(([src]) => src.endsWith(".css") || src.endsWith(".js"))
|
|
281
|
+
.map(async ([src, asset]) => {
|
|
282
|
+
const type = src.endsWith(".css") ? "style" : "js";
|
|
283
|
+
const code = atob(asset.data);
|
|
284
|
+
return {
|
|
285
|
+
code,
|
|
286
|
+
inline: false,
|
|
287
|
+
integrity: await hash(code),
|
|
288
|
+
src,
|
|
289
|
+
type,
|
|
290
|
+
};
|
|
291
|
+
}));
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
const client_dir = this.root.join(location.client);
|
|
295
|
+
const files = await client_dir.exists()
|
|
296
|
+
? await client_dir.collect(f => f.extension === ".js"
|
|
297
|
+
|| f.extension === ".css")
|
|
298
|
+
: [];
|
|
299
|
+
this.#assets = await Promise.all(files.map(async (file) => {
|
|
300
|
+
const type = file.extension === ".css" ? "style" : "js";
|
|
301
|
+
const code = await file.text();
|
|
302
|
+
return {
|
|
303
|
+
code,
|
|
304
|
+
inline: false,
|
|
305
|
+
integrity: await hash(code),
|
|
306
|
+
src: `/${file.name}`,
|
|
307
|
+
type,
|
|
308
|
+
};
|
|
309
|
+
}));
|
|
310
|
+
}
|
|
236
311
|
const modules = [
|
|
237
312
|
this.#builtins.dev,
|
|
238
313
|
...this.modules,
|
|
@@ -306,9 +381,5 @@ export default class ServeApp extends App {
|
|
|
306
381
|
},
|
|
307
382
|
};
|
|
308
383
|
}
|
|
309
|
-
get session() {
|
|
310
|
-
return this.#init.session_config;
|
|
311
|
-
}
|
|
312
|
-
;
|
|
313
384
|
}
|
|
314
|
-
//# sourceMappingURL=
|
|
385
|
+
//# sourceMappingURL=App.js.map
|
|
@@ -1,29 +1,33 @@
|
|
|
1
|
-
import type Asset from "#asset/Asset";
|
|
2
1
|
import type Config from "#config/Config";
|
|
3
2
|
import type I18NConfig from "#i18n/Config";
|
|
4
|
-
import type Loader from "#Loader";
|
|
5
3
|
import type Mode from "#Mode";
|
|
6
4
|
import type SessionConfig from "#session/Config";
|
|
7
5
|
import type Dict from "@rcompat/type/Dict";
|
|
8
6
|
type Import = {
|
|
9
7
|
default: unknown;
|
|
10
8
|
} & Dict;
|
|
11
|
-
type BuildFiles = {
|
|
12
|
-
routes: [string, {
|
|
13
|
-
default: any;
|
|
14
|
-
}][];
|
|
15
|
-
};
|
|
16
9
|
type ServeInit = {
|
|
17
|
-
assets:
|
|
10
|
+
assets: {
|
|
11
|
+
client: Dict<{
|
|
12
|
+
mime: string;
|
|
13
|
+
data: string;
|
|
14
|
+
}>;
|
|
15
|
+
static: Dict<{
|
|
16
|
+
mime: string;
|
|
17
|
+
data: string;
|
|
18
|
+
}>;
|
|
19
|
+
};
|
|
18
20
|
views?: [string, Import][];
|
|
19
21
|
stores?: [string, Import][];
|
|
20
22
|
config: Config;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
routes: [string, {
|
|
24
|
+
default: any;
|
|
25
|
+
}][];
|
|
23
26
|
mode: Mode;
|
|
24
27
|
target: string;
|
|
25
|
-
|
|
28
|
+
pages: Dict<string>;
|
|
29
|
+
session_config?: SessionConfig;
|
|
26
30
|
i18n_config?: I18NConfig;
|
|
27
31
|
};
|
|
28
32
|
export type { ServeInit as default };
|
|
29
|
-
//# sourceMappingURL=
|
|
33
|
+
//# sourceMappingURL=Init.d.ts.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import Module from "#Module";
|
|
2
2
|
import type NextHandle from "#module/NextHandle";
|
|
3
3
|
import type RequestFacade from "#request/RequestFacade";
|
|
4
|
-
import type ServeApp from "#
|
|
4
|
+
import type ServeApp from "#serve/App";
|
|
5
5
|
export default class DevModule extends Module {
|
|
6
6
|
#private;
|
|
7
7
|
name: string;
|
|
8
8
|
constructor(app: ServeApp);
|
|
9
9
|
handle(request: RequestFacade, next: NextHandle): import("@rcompat/type/MaybePromise").default<Response>;
|
|
10
10
|
}
|
|
11
|
-
//# sourceMappingURL=
|
|
11
|
+
//# sourceMappingURL=Dev.d.ts.map
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
+
import reload from "#build/client/reload";
|
|
1
2
|
import Module from "#Module";
|
|
2
|
-
import reload_defaults from "@rcompat/build/reload/defaults";
|
|
3
|
-
import reload_path from "@rcompat/build/reload/path";
|
|
4
3
|
function pass(address, request) {
|
|
5
4
|
return fetch(address, {
|
|
6
5
|
body: request.body,
|
|
@@ -16,9 +15,8 @@ export default class DevModule extends Module {
|
|
|
16
15
|
constructor(app) {
|
|
17
16
|
super();
|
|
18
17
|
const assets = app.assets.map(asset => asset.src);
|
|
19
|
-
|
|
20
|
-
this.#
|
|
21
|
-
this.#reload_url = `http://${http.host}:${reload_defaults.port}`;
|
|
18
|
+
this.#paths = ([reload.path]).concat(assets);
|
|
19
|
+
this.#reload_url = `http://${reload.host}:${reload.port}`;
|
|
22
20
|
}
|
|
23
21
|
handle(request, next) {
|
|
24
22
|
const { pathname } = new URL(request.url);
|
|
@@ -27,4 +25,4 @@ export default class DevModule extends Module {
|
|
|
27
25
|
: next(request);
|
|
28
26
|
}
|
|
29
27
|
}
|
|
30
|
-
//# sourceMappingURL=
|
|
28
|
+
//# sourceMappingURL=Dev.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import Module from "#Module";
|
|
2
2
|
import type RequestFacade from "#request/RequestFacade";
|
|
3
|
-
import type ServeApp from "#
|
|
3
|
+
import type ServeApp from "#serve/App";
|
|
4
4
|
export default class HandleModule extends Module {
|
|
5
5
|
#private;
|
|
6
6
|
name: string;
|
|
7
7
|
constructor(app: ServeApp);
|
|
8
8
|
handle(request: RequestFacade): Promise<Response>;
|
|
9
9
|
}
|
|
10
|
-
//# sourceMappingURL=
|
|
10
|
+
//# sourceMappingURL=Handle.d.ts.map
|
|
@@ -8,8 +8,8 @@ export default class HandleModule extends Module {
|
|
|
8
8
|
this.#app = app;
|
|
9
9
|
}
|
|
10
10
|
async handle(request) {
|
|
11
|
-
return await this.#app.
|
|
11
|
+
return await this.#app.serveAsset(request.url.pathname)
|
|
12
12
|
?? route(this.#app, request);
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
-
//# sourceMappingURL=
|
|
15
|
+
//# sourceMappingURL=Handle.js.map
|
|
@@ -2,11 +2,12 @@ import Module from "#Module";
|
|
|
2
2
|
import type NextHandle from "#module/NextHandle";
|
|
3
3
|
import type NextServe from "#module/NextServe";
|
|
4
4
|
import type RequestFacade from "#request/RequestFacade";
|
|
5
|
-
import type ServeApp from "#
|
|
5
|
+
import type ServeApp from "#serve/App";
|
|
6
|
+
import type Config from "#session/Config";
|
|
6
7
|
export default class SessionModule extends Module {
|
|
7
8
|
#private;
|
|
8
9
|
name: string;
|
|
9
|
-
constructor(
|
|
10
|
+
constructor(secure: boolean, config: Config);
|
|
10
11
|
serve(app: ServeApp, next: NextServe): Promise<ServeApp>;
|
|
11
12
|
handle(request: RequestFacade, next: NextHandle): Promise<Response>;
|
|
12
13
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import fail from "#fail";
|
|
1
2
|
import Module from "#Module";
|
|
2
3
|
import kSerialize from "#session/k-serialize";
|
|
3
4
|
import SessionHandle from "#session/SessionHandle";
|
|
4
5
|
import storage from "#session/storage";
|
|
6
|
+
import p from "pema";
|
|
5
7
|
const cookie = (name, value, options) => {
|
|
6
8
|
const parts = [`${name}=${value}`];
|
|
7
9
|
parts.push(`Path=${options.path}`);
|
|
@@ -16,26 +18,47 @@ const cookie = (name, value, options) => {
|
|
|
16
18
|
};
|
|
17
19
|
export default class SessionModule extends Module {
|
|
18
20
|
name = "builtin/session";
|
|
19
|
-
#
|
|
20
|
-
#manager;
|
|
21
|
+
#store;
|
|
21
22
|
#secure;
|
|
22
|
-
|
|
23
|
+
#config;
|
|
24
|
+
constructor(secure, config) {
|
|
23
25
|
super();
|
|
24
|
-
this.#
|
|
25
|
-
this.#
|
|
26
|
-
this.#
|
|
26
|
+
this.#secure = secure;
|
|
27
|
+
this.#config = config;
|
|
28
|
+
this.#store = config.store;
|
|
29
|
+
const props = this.#store.type.properties;
|
|
30
|
+
if (!("session_id" in props)) {
|
|
31
|
+
throw fail("Session store must have a session_id field");
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
props.session_id.parse(crypto.randomUUID());
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
throw fail("Session store session_id must be a string type");
|
|
38
|
+
}
|
|
27
39
|
}
|
|
28
40
|
async serve(app, next) {
|
|
29
|
-
|
|
30
|
-
await this.#manager.init?.();
|
|
41
|
+
await this.#store.collection.create();
|
|
31
42
|
return next(app);
|
|
32
43
|
}
|
|
33
44
|
async handle(request, next) {
|
|
34
|
-
const { name, ...config } = this.#
|
|
45
|
+
const { name, ...config } = this.#config.cookie;
|
|
35
46
|
const sid = request.cookies.try(name);
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
|
|
47
|
+
// Look up session by session_id
|
|
48
|
+
const existing = sid !== undefined
|
|
49
|
+
? await this.#store.find({ session_id: sid }, { limit: 1 })
|
|
50
|
+
: [];
|
|
51
|
+
const exists = existing.length > 0;
|
|
52
|
+
let data = undefined;
|
|
53
|
+
let dbId = undefined;
|
|
54
|
+
if (exists) {
|
|
55
|
+
const record = existing[0];
|
|
56
|
+
const { id: _id, session_id: _sid, ...rest } = record;
|
|
57
|
+
data = rest;
|
|
58
|
+
dbId = _id;
|
|
59
|
+
}
|
|
60
|
+
const session_type = p.omit(this.#store.type, "id", "session_id");
|
|
61
|
+
const session = new SessionHandle(sid, data, session_type);
|
|
39
62
|
const response = await new Promise((resolve, reject) => {
|
|
40
63
|
storage().run(session, async () => {
|
|
41
64
|
try {
|
|
@@ -56,10 +79,10 @@ export default class SessionModule extends Module {
|
|
|
56
79
|
sameSite: config.sameSite,
|
|
57
80
|
secure: this.#secure,
|
|
58
81
|
};
|
|
59
|
-
// no session existed -> either create or noop
|
|
60
|
-
if (
|
|
82
|
+
// no session existed -> either create or noop
|
|
83
|
+
if (!exists) {
|
|
61
84
|
if (!snap.exists) {
|
|
62
|
-
// stale cookie -> clear
|
|
85
|
+
// stale cookie -> clear
|
|
63
86
|
if (sid !== undefined) {
|
|
64
87
|
response.headers.append("set-cookie", cookie(name, "", {
|
|
65
88
|
...options, maxAge: 0,
|
|
@@ -67,32 +90,32 @@ export default class SessionModule extends Module {
|
|
|
67
90
|
}
|
|
68
91
|
return response;
|
|
69
92
|
}
|
|
70
|
-
//
|
|
71
|
-
await this.#
|
|
93
|
+
// create new session
|
|
94
|
+
await this.#store.insert({ session_id: snap.id, ...snap.data });
|
|
72
95
|
response.headers.append("set-cookie", cookie(name, snap.id, options));
|
|
73
96
|
return response;
|
|
74
97
|
}
|
|
75
|
-
// from here: session existed (
|
|
98
|
+
// from here: session existed (dbId is defined)
|
|
76
99
|
// fast-path: session exists, same id and not dirty -> noop
|
|
77
|
-
if (snap.exists && snap.id ===
|
|
100
|
+
if (snap.exists && snap.id === sid && !snap.dirty)
|
|
78
101
|
return response;
|
|
79
102
|
// current absent -> destroy + clear cookie
|
|
80
103
|
if (!snap.exists) {
|
|
81
|
-
await this.#
|
|
104
|
+
await this.#store.delete(dbId);
|
|
82
105
|
response.headers.append("set-cookie", cookie(name, "", {
|
|
83
106
|
...options, maxAge: 0,
|
|
84
107
|
}));
|
|
85
108
|
return response;
|
|
86
109
|
}
|
|
87
110
|
// session recreated in route -> destroy old, create new, set cookie
|
|
88
|
-
if (snap.id !==
|
|
89
|
-
await this.#
|
|
90
|
-
await this.#
|
|
111
|
+
if (snap.id !== sid) {
|
|
112
|
+
await this.#store.delete(dbId);
|
|
113
|
+
await this.#store.insert({ session_id: snap.id, ...snap.data });
|
|
91
114
|
response.headers.append("set-cookie", cookie(name, snap.id, options));
|
|
92
115
|
return response;
|
|
93
116
|
}
|
|
94
117
|
// dirty -> replace session contents
|
|
95
|
-
await this.#
|
|
118
|
+
await this.#store.update(dbId, snap.data);
|
|
96
119
|
return response;
|
|
97
120
|
}
|
|
98
121
|
}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
+
import type DatabaseStore from "#database/Store";
|
|
1
2
|
import configSchema from "#session/schema";
|
|
2
3
|
import type SessionFacade from "#session/SessionFacade";
|
|
3
|
-
import type
|
|
4
|
+
import type InferStore from "pema/InferStore";
|
|
5
|
+
import type StoreSchema from "pema/StoreSchema";
|
|
4
6
|
type ConfigInput = typeof configSchema.input;
|
|
5
|
-
type
|
|
6
|
-
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
type X<T> = {
|
|
8
|
+
[K in keyof T]: T[K];
|
|
9
|
+
} & {};
|
|
10
|
+
type Infer<S extends StoreSchema> = X<Omit<InferStore<S>, "id" | "session_id">>;
|
|
11
|
+
export default function session<S extends StoreSchema>(config: {
|
|
12
|
+
store: DatabaseStore<S>;
|
|
13
|
+
} & Partial<ConfigInput>): SessionFacade<Infer<S>>;
|
|
14
|
+
export default function session(Infer?: Omit<Partial<ConfigInput>, "store">): SessionFacade<unknown>;
|
|
12
15
|
export {};
|
|
13
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -3,8 +3,8 @@ import local_storage from "#session/storage";
|
|
|
3
3
|
import s_config from "#symbol/config";
|
|
4
4
|
export default function session(config) {
|
|
5
5
|
const parsed = configSchema.parse(config ?? {});
|
|
6
|
-
const
|
|
7
|
-
// bind the ALS store to this T
|
|
6
|
+
const store = parsed.store;
|
|
7
|
+
// bind the ALS store to this T
|
|
8
8
|
const storage = local_storage();
|
|
9
9
|
const current = () => {
|
|
10
10
|
const s = storage.getStore();
|
|
@@ -34,7 +34,9 @@ export default function session(config) {
|
|
|
34
34
|
destroy() {
|
|
35
35
|
current().destroy();
|
|
36
36
|
},
|
|
37
|
-
get [s_config]() {
|
|
37
|
+
get [s_config]() {
|
|
38
|
+
return { ...parsed, store };
|
|
39
|
+
},
|
|
38
40
|
};
|
|
39
41
|
return facade;
|
|
40
42
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type Schema from "@rcompat/type/Schema";
|
|
1
|
+
import Store from "#database/Store";
|
|
3
2
|
declare const _default: import("pema").ObjectType<{
|
|
4
3
|
cookie: import("pema").ObjectType<{
|
|
5
4
|
httpOnly: import("pema").DefaultType<import("pema/boolean").BooleanType, true>;
|
|
@@ -7,8 +6,7 @@ declare const _default: import("pema").ObjectType<{
|
|
|
7
6
|
path: import("pema").DefaultType<import("pema/string").StringType, "/">;
|
|
8
7
|
sameSite: import("pema").DefaultType<import("pema/union").UnionType<[import("pema").LiteralType<"Strict">, import("pema").LiteralType<"Lax">, import("pema").LiteralType<"None">]>, "Lax" | "None" | "Strict">;
|
|
9
8
|
}>;
|
|
10
|
-
|
|
11
|
-
schema: import("pema").OptionalType<import("pema").PureType<Schema<unknown>, "PureType">>;
|
|
9
|
+
store: import("pema").DefaultType<import("pema").ConstructorType<typeof Store>, Store<import("pema/StoreSchema").default>>;
|
|
12
10
|
}>;
|
|
13
11
|
export default _default;
|
|
14
12
|
//# sourceMappingURL=schema.d.ts.map
|