oxidejs 0.2.3 → 0.2.4
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 +2 -0
- package/dist/index.d.mts +1 -7
- package/dist/index.mjs +49 -2
- package/dist/{src-D-qdNVqg.mjs → plugin-nO0yjtk0.mjs} +96 -96
- package/dist/plugin.d.mts +8 -0
- package/dist/plugin.mjs +2 -0
- package/dist/rsbuild.mjs +1 -1
- package/dist/vite.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,6 +12,8 @@ dist/
|
|
|
12
12
|
|
|
13
13
|
v1 targets **Vite** and **Rsbuild** via unplugin. Other bundlers are out of scope for now.
|
|
14
14
|
|
|
15
|
+
The `oxidejs` entry exports runtime helpers (`action`, `useRequest`, …). The bundler plugin lives at `oxidejs/vite` or `oxidejs/rsbuild` — keep those separate so `*.server.ts` can import `oxidejs` under `preset: "celld"` without pulling Node build tooling into the worker graph.
|
|
16
|
+
|
|
15
17
|
## Vite
|
|
16
18
|
|
|
17
19
|
```ts
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { a as OxidejsWranglerOptions, i as OxidejsPreset, n as OxidejsActionTransport, o as ResolvedOptions, r as OxidejsOptions, t as OxidejsActionHeaders } from "./types-BM4NAnzy.mjs";
|
|
2
|
-
import { UnpluginFactory } from "unplugin";
|
|
3
2
|
//#region src/context.d.ts
|
|
4
3
|
type ExecutionContext = {
|
|
5
4
|
waitUntil?(promise: Promise<unknown>): void;
|
|
@@ -28,9 +27,4 @@ declare function action<Args extends unknown[], Result>(fn: (...args: Args) => R
|
|
|
28
27
|
signal?: AbortSignal;
|
|
29
28
|
}]) => Result);
|
|
30
29
|
//#endregion
|
|
31
|
-
|
|
32
|
-
declare const unpluginFactory: UnpluginFactory<OxidejsOptions | undefined>;
|
|
33
|
-
declare const oxidejs: import("unplugin").UnpluginInstance<OxidejsOptions | undefined, boolean>;
|
|
34
|
-
declare const vite: (options?: OxidejsOptions | undefined) => import("vite").Plugin<any> | import("vite").Plugin<any>[];
|
|
35
|
-
//#endregion
|
|
36
|
-
export { type ActionContext, type ExecutionContext, type OxidejsActionHeaders, type OxidejsActionTransport, type OxidejsOptions, type OxidejsPreset, type OxidejsWranglerOptions, type ResolvedOptions, action, oxidejs as default, oxidejs, unpluginFactory, useCtx, useEnv, useFetchCtx, useRequest, vite };
|
|
30
|
+
export { type ActionContext, type ExecutionContext, type OxidejsActionHeaders, type OxidejsActionTransport, type OxidejsOptions, type OxidejsPreset, type OxidejsWranglerOptions, type ResolvedOptions, action, useCtx, useEnv, useFetchCtx, useRequest };
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,49 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
//#region src/context.ts
|
|
3
|
+
const ALS_KEY = Symbol.for("oxidejs.requestContext");
|
|
4
|
+
const FETCH_KEY = Symbol.for("oxidejs.fetch");
|
|
5
|
+
function als() {
|
|
6
|
+
const g = globalThis;
|
|
7
|
+
return g[ALS_KEY] ??= new AsyncLocalStorage();
|
|
8
|
+
}
|
|
9
|
+
function store() {
|
|
10
|
+
const current = als().getStore();
|
|
11
|
+
if (!current) throw new Error("oxidejs: request context is unavailable");
|
|
12
|
+
return current;
|
|
13
|
+
}
|
|
14
|
+
/** Current tacho or host request context. Throws outside request handling. */
|
|
15
|
+
function useCtx() {
|
|
16
|
+
return store();
|
|
17
|
+
}
|
|
18
|
+
/** Current server `Request`. Available in actions, SSR, and frame renders. */
|
|
19
|
+
function useRequest() {
|
|
20
|
+
return store().req;
|
|
21
|
+
}
|
|
22
|
+
/** Worker `env` from `fetch(request, env, ctx)`. `undefined` on the Node fetch preset. */
|
|
23
|
+
function useEnv() {
|
|
24
|
+
return store().env;
|
|
25
|
+
}
|
|
26
|
+
/** Worker `ctx` from `fetch(request, env, ctx)` (`waitUntil`). Not tacho `ctx`. `undefined` on Node. */
|
|
27
|
+
function useFetchCtx() {
|
|
28
|
+
return store().fetchCtx;
|
|
29
|
+
}
|
|
30
|
+
function runWithRequest(req, fn, extra) {
|
|
31
|
+
return als().run({
|
|
32
|
+
...extra,
|
|
33
|
+
req
|
|
34
|
+
}, fn);
|
|
35
|
+
}
|
|
36
|
+
const HOOK_KEY = Symbol.for("oxidejs.runWithRequest");
|
|
37
|
+
globalThis[HOOK_KEY] ??= (req, fn) => {
|
|
38
|
+
const extra = req[FETCH_KEY];
|
|
39
|
+
return runWithRequest(req, fn, extra);
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Marks a `*.server.ts` export as a remote RPC action. Runtime identity; the
|
|
43
|
+
* second call signature adds the transport-only `{ signal }` argument.
|
|
44
|
+
*/
|
|
45
|
+
function action(fn) {
|
|
46
|
+
return fn;
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
export { action, useCtx, useEnv, useFetchCtx, useRequest };
|
|
@@ -2,7 +2,6 @@ import { createUnplugin } from "unplugin";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { pathToFileURL } from "node:url";
|
|
4
4
|
import fs from "node:fs";
|
|
5
|
-
import { AsyncLocalStorage } from "node:async_hooks";
|
|
6
5
|
//#region \0rolldown/runtime.js
|
|
7
6
|
var __defProp = Object.defineProperty;
|
|
8
7
|
var __exportAll = (all, no_symbols) => {
|
|
@@ -684,55 +683,8 @@ function applyRsbuildEnvironments(config, opts) {
|
|
|
684
683
|
return config;
|
|
685
684
|
}
|
|
686
685
|
//#endregion
|
|
687
|
-
//#region src/
|
|
688
|
-
|
|
689
|
-
const FETCH_KEY = Symbol.for("oxidejs.fetch");
|
|
690
|
-
function als() {
|
|
691
|
-
const g = globalThis;
|
|
692
|
-
return g[ALS_KEY] ??= new AsyncLocalStorage();
|
|
693
|
-
}
|
|
694
|
-
function store() {
|
|
695
|
-
const current = als().getStore();
|
|
696
|
-
if (!current) throw new Error("oxidejs: request context is unavailable");
|
|
697
|
-
return current;
|
|
698
|
-
}
|
|
699
|
-
/** Current tacho or host request context. Throws outside request handling. */
|
|
700
|
-
function useCtx() {
|
|
701
|
-
return store();
|
|
702
|
-
}
|
|
703
|
-
/** Current server `Request`. Available in actions, SSR, and frame renders. */
|
|
704
|
-
function useRequest() {
|
|
705
|
-
return store().req;
|
|
706
|
-
}
|
|
707
|
-
/** Worker `env` from `fetch(request, env, ctx)`. `undefined` on the Node fetch preset. */
|
|
708
|
-
function useEnv() {
|
|
709
|
-
return store().env;
|
|
710
|
-
}
|
|
711
|
-
/** Worker `ctx` from `fetch(request, env, ctx)` (`waitUntil`). Not tacho `ctx`. `undefined` on Node. */
|
|
712
|
-
function useFetchCtx() {
|
|
713
|
-
return store().fetchCtx;
|
|
714
|
-
}
|
|
715
|
-
function runWithRequest(req, fn, extra) {
|
|
716
|
-
return als().run({
|
|
717
|
-
...extra,
|
|
718
|
-
req
|
|
719
|
-
}, fn);
|
|
720
|
-
}
|
|
721
|
-
const HOOK_KEY = Symbol.for("oxidejs.runWithRequest");
|
|
722
|
-
globalThis[HOOK_KEY] ??= (req, fn) => {
|
|
723
|
-
const extra = req[FETCH_KEY];
|
|
724
|
-
return runWithRequest(req, fn, extra);
|
|
725
|
-
};
|
|
726
|
-
/**
|
|
727
|
-
* Marks a `*.server.ts` export as a remote RPC action. Runtime identity; the
|
|
728
|
-
* second call signature adds the transport-only `{ signal }` argument.
|
|
729
|
-
*/
|
|
730
|
-
function action(fn) {
|
|
731
|
-
return fn;
|
|
732
|
-
}
|
|
733
|
-
//#endregion
|
|
734
|
-
//#region src/index.ts
|
|
735
|
-
function actionMiddleware(loadRouter, path, sameOrigin, bodyLimit) {
|
|
686
|
+
//#region src/plugin.ts
|
|
687
|
+
function actionMiddleware(loadRouter, path, sameOrigin, bodyLimit, onError) {
|
|
736
688
|
return (req, res, next) => {
|
|
737
689
|
if ((req.url ?? "").split("?")[0] !== path) {
|
|
738
690
|
next();
|
|
@@ -748,10 +700,16 @@ function actionMiddleware(loadRouter, path, sameOrigin, bodyLimit) {
|
|
|
748
700
|
...sameOrigin ? { sameOrigin: true } : {}
|
|
749
701
|
})(await nodeToWebRequest(req, bodyLimit)));
|
|
750
702
|
})().catch((error) => {
|
|
703
|
+
if (res.headersSent) return;
|
|
751
704
|
if (error instanceof RequestBodyTooLargeError) {
|
|
752
705
|
res.statusCode = 413;
|
|
753
706
|
res.end();
|
|
754
|
-
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
709
|
+
onError?.(error);
|
|
710
|
+
res.statusCode = 503;
|
|
711
|
+
res.setHeader("content-type", "application/json");
|
|
712
|
+
res.end(JSON.stringify({ error: "oxide action handler failed" }));
|
|
755
713
|
});
|
|
756
714
|
};
|
|
757
715
|
}
|
|
@@ -864,60 +822,102 @@ const unpluginFactory = (options) => {
|
|
|
864
822
|
if (mod) env.moduleGraph.invalidateModule(mod);
|
|
865
823
|
}
|
|
866
824
|
};
|
|
825
|
+
const fetchRouter = async () => {
|
|
826
|
+
return (await server.ssrLoadModule(VIRTUAL_ACTIONS_ID)).default;
|
|
827
|
+
};
|
|
828
|
+
let routerReady;
|
|
829
|
+
const loadRouter = () => {
|
|
830
|
+
const current = routerReady ??= fetchRouter();
|
|
831
|
+
return current.catch((error) => {
|
|
832
|
+
if (routerReady === current) routerReady = void 0;
|
|
833
|
+
throw error;
|
|
834
|
+
});
|
|
835
|
+
};
|
|
836
|
+
const refreshRouter = () => {
|
|
837
|
+
routerReady = void 0;
|
|
838
|
+
};
|
|
867
839
|
server.watcher.on("all", (_event, file) => {
|
|
868
|
-
if (isServerFileId(file))
|
|
840
|
+
if (isServerFileId(file)) {
|
|
841
|
+
invalidateActions();
|
|
842
|
+
refreshRouter();
|
|
843
|
+
}
|
|
869
844
|
});
|
|
870
|
-
const
|
|
871
|
-
|
|
845
|
+
const logActionError = (error) => {
|
|
846
|
+
server.config.logger.error("oxidejs: action handler failed: " + String(error));
|
|
872
847
|
};
|
|
873
|
-
const wireActions = () => server.middlewares.use(actionMiddleware(loadRouter, resolved.actionPath, resolved.actionSameOrigin, resolved.bodyLimit));
|
|
848
|
+
const wireActions = () => server.middlewares.use(actionMiddleware(loadRouter, resolved.actionPath, resolved.actionSameOrigin, resolved.bodyLimit, logActionError));
|
|
874
849
|
if (resolved?.actions === "ws") {
|
|
875
850
|
attachActionUpgrade(server.httpServer, loadRouter, resolved.actionPath, resolved.actionSameOrigin);
|
|
876
|
-
return
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
851
|
+
return async () => {
|
|
852
|
+
try {
|
|
853
|
+
await loadRouter();
|
|
854
|
+
} catch (error) {
|
|
855
|
+
server.config.logger.error("oxidejs: failed to prewarm actions: " + String(error));
|
|
856
|
+
}
|
|
857
|
+
};
|
|
881
858
|
}
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
const
|
|
888
|
-
const
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
859
|
+
let handlersPromise = Promise.resolve([]);
|
|
860
|
+
if ((resolved?.middleware?.length ?? 0) > 0 || (resolved?.imports?.length ?? 0) > 0) {
|
|
861
|
+
handlersPromise = (async () => {
|
|
862
|
+
try {
|
|
863
|
+
for (const spec of resolved.imports ?? []) await server.ssrLoadModule(spec);
|
|
864
|
+
const handlers = [];
|
|
865
|
+
for (const entry of resolved.middleware ?? []) {
|
|
866
|
+
const spec = typeof entry === "string" ? entry : entry.module;
|
|
867
|
+
const mod = await server.ssrLoadModule(spec);
|
|
868
|
+
if (typeof mod.default !== "function") continue;
|
|
869
|
+
const fn = mod.default;
|
|
870
|
+
handlers.push((request, context) => Promise.resolve(fn(request, context)));
|
|
871
|
+
}
|
|
872
|
+
return handlers;
|
|
873
|
+
} catch (error) {
|
|
874
|
+
server.config.logger.error("oxidejs: failed to wire dev middleware: " + String(error));
|
|
875
|
+
return [];
|
|
892
876
|
}
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
const request = await nodeToWebRequest(creq, resolved.bodyLimit);
|
|
899
|
-
const context = {
|
|
900
|
-
env: resolved.env,
|
|
901
|
-
ctx: void 0
|
|
902
|
-
};
|
|
903
|
-
for (const handler of handlers) {
|
|
904
|
-
const hit = await handler(request, context);
|
|
905
|
-
if (hit) return sendWebResponseFrom(creq, cres, hit);
|
|
906
|
-
}
|
|
907
|
-
next();
|
|
908
|
-
} catch (error) {
|
|
909
|
-
cres.statusCode = error instanceof RequestBodyTooLargeError ? 413 : 500;
|
|
910
|
-
cres.end(error instanceof RequestBodyTooLargeError ? void 0 : String(error));
|
|
911
|
-
}
|
|
912
|
-
})();
|
|
913
|
-
});
|
|
877
|
+
})();
|
|
878
|
+
server.middlewares.use((creq, cres, next) => {
|
|
879
|
+
if ((creq.url ?? "").split("?")[0] === resolved.actionPath) {
|
|
880
|
+
next();
|
|
881
|
+
return;
|
|
914
882
|
}
|
|
883
|
+
(async () => {
|
|
884
|
+
try {
|
|
885
|
+
const handlers = await handlersPromise;
|
|
886
|
+
if (handlers.length === 0) {
|
|
887
|
+
next();
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
890
|
+
const { nodeToWebRequest, sendWebResponseFrom } = await Promise.resolve().then(() => actions_exports);
|
|
891
|
+
const request = await nodeToWebRequest(creq, resolved.bodyLimit);
|
|
892
|
+
const context = {
|
|
893
|
+
env: resolved.env,
|
|
894
|
+
ctx: void 0
|
|
895
|
+
};
|
|
896
|
+
for (const handler of handlers) {
|
|
897
|
+
const hit = await handler(request, context);
|
|
898
|
+
if (hit) {
|
|
899
|
+
await sendWebResponseFrom(creq, cres, hit);
|
|
900
|
+
return;
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
next();
|
|
904
|
+
} catch (error) {
|
|
905
|
+
if (cres.headersSent) return;
|
|
906
|
+
cres.statusCode = error instanceof RequestBodyTooLargeError ? 413 : 500;
|
|
907
|
+
cres.end(error instanceof RequestBodyTooLargeError ? void 0 : String(error));
|
|
908
|
+
}
|
|
909
|
+
})();
|
|
910
|
+
});
|
|
911
|
+
}
|
|
912
|
+
wireActions();
|
|
913
|
+
return async () => {
|
|
914
|
+
try {
|
|
915
|
+
await loadRouter();
|
|
916
|
+
await handlersPromise;
|
|
915
917
|
} catch (error) {
|
|
916
|
-
server.config.logger.error("oxidejs: failed to
|
|
917
|
-
} finally {
|
|
918
|
-
wireActions();
|
|
918
|
+
server.config.logger.error("oxidejs: failed to prewarm dev server: " + String(error));
|
|
919
919
|
}
|
|
920
|
-
}
|
|
920
|
+
};
|
|
921
921
|
},
|
|
922
922
|
configurePreviewServer(server) {
|
|
923
923
|
if (resolved?.preset !== "fetch") return;
|
|
@@ -951,4 +951,4 @@ const unpluginFactory = (options) => {
|
|
|
951
951
|
const oxidejs = /* @__PURE__ */ createUnplugin(unpluginFactory);
|
|
952
952
|
const vite = /* @__PURE__ */ (() => oxidejs.vite)();
|
|
953
953
|
//#endregion
|
|
954
|
-
export {
|
|
954
|
+
export { unpluginFactory as n, vite as r, oxidejs as t };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { r as OxidejsOptions } from "./types-BM4NAnzy.mjs";
|
|
2
|
+
import { UnpluginFactory } from "unplugin";
|
|
3
|
+
//#region src/plugin.d.ts
|
|
4
|
+
declare const unpluginFactory: UnpluginFactory<OxidejsOptions | undefined>;
|
|
5
|
+
declare const oxidejs: import("unplugin").UnpluginInstance<OxidejsOptions | undefined, boolean>;
|
|
6
|
+
declare const vite: (options?: OxidejsOptions | undefined) => import("vite").Plugin<any> | import("vite").Plugin<any>[];
|
|
7
|
+
//#endregion
|
|
8
|
+
export { oxidejs as default, oxidejs, unpluginFactory, vite };
|
package/dist/plugin.mjs
ADDED
package/dist/rsbuild.mjs
CHANGED
package/dist/vite.mjs
CHANGED