@alepha/react 0.9.0 → 0.9.2
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 +7 -0
- package/dist/index.browser.js +104 -41
- package/dist/index.browser.js.map +1 -1
- package/dist/index.cjs +109 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +55 -31
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +56 -32
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +107 -43
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/components/ErrorViewer.tsx +4 -3
- package/src/contexts/AlephaContext.ts +4 -0
- package/src/contexts/RouterContext.ts +0 -2
- package/src/hooks/useAlepha.ts +5 -5
- package/src/hooks/useInject.ts +5 -8
- package/src/hooks/useQueryParams.ts +6 -9
- package/src/hooks/useRouter.ts +4 -4
- package/src/hooks/useRouterEvents.ts +7 -10
- package/src/hooks/useRouterState.ts +6 -4
- package/src/hooks/useSchema.ts +93 -0
- package/src/hooks/useStore.ts +39 -0
- package/src/index.shared.ts +3 -0
- package/src/providers/PageDescriptorProvider.ts +13 -9
- package/src/providers/ReactBrowserProvider.ts +1 -1
- package/src/providers/ReactServerProvider.ts +6 -2
package/dist/index.cjs
CHANGED
|
@@ -74,23 +74,11 @@ const ClientOnly = (props) => {
|
|
|
74
74
|
};
|
|
75
75
|
var ClientOnly_default = ClientOnly;
|
|
76
76
|
|
|
77
|
-
//#endregion
|
|
78
|
-
//#region src/contexts/RouterContext.ts
|
|
79
|
-
const RouterContext = (0, react.createContext)(void 0);
|
|
80
|
-
|
|
81
|
-
//#endregion
|
|
82
|
-
//#region src/hooks/useAlepha.ts
|
|
83
|
-
const useAlepha = () => {
|
|
84
|
-
const routerContext = (0, react.useContext)(RouterContext);
|
|
85
|
-
if (!routerContext) throw new Error("useAlepha must be used within a RouterProvider");
|
|
86
|
-
return routerContext.alepha;
|
|
87
|
-
};
|
|
88
|
-
|
|
89
77
|
//#endregion
|
|
90
78
|
//#region src/components/ErrorViewer.tsx
|
|
91
|
-
const ErrorViewer = ({ error }) => {
|
|
79
|
+
const ErrorViewer = ({ error, alepha }) => {
|
|
92
80
|
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
93
|
-
const isProduction =
|
|
81
|
+
const isProduction = alepha.isProduction();
|
|
94
82
|
if (isProduction) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ErrorViewerProduction, {});
|
|
95
83
|
const stackLines = error.stack?.split("\n") ?? [];
|
|
96
84
|
const previewLines = stackLines.slice(0, 5);
|
|
@@ -234,24 +222,39 @@ const ErrorViewerProduction = () => {
|
|
|
234
222
|
});
|
|
235
223
|
};
|
|
236
224
|
|
|
225
|
+
//#endregion
|
|
226
|
+
//#region src/contexts/RouterContext.ts
|
|
227
|
+
const RouterContext = (0, react.createContext)(void 0);
|
|
228
|
+
|
|
237
229
|
//#endregion
|
|
238
230
|
//#region src/contexts/RouterLayerContext.ts
|
|
239
231
|
const RouterLayerContext = (0, react.createContext)(void 0);
|
|
240
232
|
|
|
233
|
+
//#endregion
|
|
234
|
+
//#region src/contexts/AlephaContext.ts
|
|
235
|
+
const AlephaContext = (0, react.createContext)(void 0);
|
|
236
|
+
|
|
237
|
+
//#endregion
|
|
238
|
+
//#region src/hooks/useAlepha.ts
|
|
239
|
+
const useAlepha = () => {
|
|
240
|
+
const alepha = (0, react.useContext)(AlephaContext);
|
|
241
|
+
if (!alepha) throw new Error("useAlepha must be used within an AlephaContext.Provider");
|
|
242
|
+
return alepha;
|
|
243
|
+
};
|
|
244
|
+
|
|
241
245
|
//#endregion
|
|
242
246
|
//#region src/hooks/useRouterEvents.ts
|
|
243
247
|
const useRouterEvents = (opts = {}, deps = []) => {
|
|
244
|
-
const
|
|
245
|
-
if (!ctx) throw new Error("useRouter must be used within a RouterProvider");
|
|
248
|
+
const alepha = useAlepha();
|
|
246
249
|
(0, react.useEffect)(() => {
|
|
247
|
-
if (!
|
|
250
|
+
if (!alepha.isBrowser()) return;
|
|
248
251
|
const subs = [];
|
|
249
252
|
const onBegin = opts.onBegin;
|
|
250
253
|
const onEnd = opts.onEnd;
|
|
251
254
|
const onError = opts.onError;
|
|
252
|
-
if (onBegin) subs.push(
|
|
253
|
-
if (onEnd) subs.push(
|
|
254
|
-
if (onError) subs.push(
|
|
255
|
+
if (onBegin) subs.push(alepha.on("react:transition:begin", { callback: onBegin }));
|
|
256
|
+
if (onEnd) subs.push(alepha.on("react:transition:end", { callback: onEnd }));
|
|
257
|
+
if (onError) subs.push(alepha.on("react:transition:error", { callback: onError }));
|
|
255
258
|
return () => {
|
|
256
259
|
for (const sub of subs) sub();
|
|
257
260
|
};
|
|
@@ -391,11 +394,10 @@ var PageDescriptorProvider = class {
|
|
|
391
394
|
return new URL(url.replace(/\/\/+/g, "/") || "/", options.base ?? `http://localhost`);
|
|
392
395
|
}
|
|
393
396
|
root(state, context) {
|
|
394
|
-
const root = (0, react.createElement)(RouterContext.Provider, { value: {
|
|
395
|
-
alepha: this.alepha,
|
|
397
|
+
const root = (0, react.createElement)(AlephaContext.Provider, { value: this.alepha }, (0, react.createElement)(RouterContext.Provider, { value: {
|
|
396
398
|
state,
|
|
397
399
|
context
|
|
398
|
-
} }, (0, react.createElement)(NestedView_default, {}, state.layers[0]?.element));
|
|
400
|
+
} }, (0, react.createElement)(NestedView_default, {}, state.layers[0]?.element)));
|
|
399
401
|
if (this.env.REACT_STRICT_MODE) return (0, react.createElement)(react.StrictMode, {}, root);
|
|
400
402
|
return root;
|
|
401
403
|
}
|
|
@@ -541,7 +543,10 @@ var PageDescriptorProvider = class {
|
|
|
541
543
|
return void 0;
|
|
542
544
|
}
|
|
543
545
|
renderError(error) {
|
|
544
|
-
return (0, react.createElement)(ErrorViewer_default, {
|
|
546
|
+
return (0, react.createElement)(ErrorViewer_default, {
|
|
547
|
+
error,
|
|
548
|
+
alepha: this.alepha
|
|
549
|
+
});
|
|
545
550
|
}
|
|
546
551
|
renderEmptyView() {
|
|
547
552
|
return (0, react.createElement)(NestedView_default, {});
|
|
@@ -834,7 +839,7 @@ var ReactBrowserProvider = class {
|
|
|
834
839
|
hydration
|
|
835
840
|
});
|
|
836
841
|
window.addEventListener("popstate", () => {
|
|
837
|
-
if (this.state.pathname ===
|
|
842
|
+
if (this.state.pathname === this.url) return;
|
|
838
843
|
this.render();
|
|
839
844
|
});
|
|
840
845
|
}
|
|
@@ -847,7 +852,8 @@ const envSchema = __alepha_core.t.object({
|
|
|
847
852
|
REACT_SERVER_DIST: __alepha_core.t.string({ default: "public" }),
|
|
848
853
|
REACT_SERVER_PREFIX: __alepha_core.t.string({ default: "" }),
|
|
849
854
|
REACT_SSR_ENABLED: __alepha_core.t.optional(__alepha_core.t.boolean()),
|
|
850
|
-
REACT_ROOT_ID: __alepha_core.t.string({ default: "root" })
|
|
855
|
+
REACT_ROOT_ID: __alepha_core.t.string({ default: "root" }),
|
|
856
|
+
REACT_SERVER_TEMPLATE: __alepha_core.t.optional(__alepha_core.t.string({ size: "rich" }))
|
|
851
857
|
});
|
|
852
858
|
var ReactServerProvider = class {
|
|
853
859
|
log = (0, __alepha_core.$logger)();
|
|
@@ -900,7 +906,7 @@ var ReactServerProvider = class {
|
|
|
900
906
|
}
|
|
901
907
|
});
|
|
902
908
|
get template() {
|
|
903
|
-
return this.alepha.
|
|
909
|
+
return this.alepha.env.REACT_SERVER_TEMPLATE ?? "<!DOCTYPE html><html lang='en'><head></head><body></body></html>";
|
|
904
910
|
}
|
|
905
911
|
async registerPages(templateLoader) {
|
|
906
912
|
for (const page of this.pageDescriptorProvider.getPages()) {
|
|
@@ -1154,13 +1160,14 @@ var RouterHookApi = class {
|
|
|
1154
1160
|
//#endregion
|
|
1155
1161
|
//#region src/hooks/useRouter.ts
|
|
1156
1162
|
const useRouter = () => {
|
|
1163
|
+
const alepha = useAlepha();
|
|
1157
1164
|
const ctx = (0, react.useContext)(RouterContext);
|
|
1158
1165
|
const layer = (0, react.useContext)(RouterLayerContext);
|
|
1159
1166
|
if (!ctx || !layer) throw new Error("useRouter must be used within a RouterProvider");
|
|
1160
1167
|
const pages = (0, react.useMemo)(() => {
|
|
1161
|
-
return
|
|
1168
|
+
return alepha.inject(PageDescriptorProvider).getPages();
|
|
1162
1169
|
}, []);
|
|
1163
|
-
return (0, react.useMemo)(() => new RouterHookApi(pages, ctx.context, ctx.state, layer,
|
|
1170
|
+
return (0, react.useMemo)(() => new RouterHookApi(pages, ctx.context, ctx.state, layer, alepha.isBrowser() ? alepha.inject(ReactBrowserProvider) : void 0), [layer]);
|
|
1164
1171
|
};
|
|
1165
1172
|
|
|
1166
1173
|
//#endregion
|
|
@@ -1221,10 +1228,9 @@ const useActive = (path) => {
|
|
|
1221
1228
|
|
|
1222
1229
|
//#endregion
|
|
1223
1230
|
//#region src/hooks/useInject.ts
|
|
1224
|
-
const useInject = (
|
|
1225
|
-
const
|
|
1226
|
-
|
|
1227
|
-
return (0, react.useMemo)(() => ctx.alepha.inject(clazz), []);
|
|
1231
|
+
const useInject = (service) => {
|
|
1232
|
+
const alepha = useAlepha();
|
|
1233
|
+
return (0, react.useMemo)(() => alepha.inject(service), []);
|
|
1228
1234
|
};
|
|
1229
1235
|
|
|
1230
1236
|
//#endregion
|
|
@@ -1236,21 +1242,20 @@ const useClient = (_scope) => {
|
|
|
1236
1242
|
//#endregion
|
|
1237
1243
|
//#region src/hooks/useQueryParams.ts
|
|
1238
1244
|
const useQueryParams = (schema, options = {}) => {
|
|
1239
|
-
const
|
|
1240
|
-
if (!ctx) throw new Error("useQueryParams must be used within a RouterProvider");
|
|
1245
|
+
const alepha = useAlepha();
|
|
1241
1246
|
const key = options.key ?? "q";
|
|
1242
1247
|
const router = useRouter();
|
|
1243
1248
|
const querystring = router.query[key];
|
|
1244
|
-
const [queryParams, setQueryParams] = (0, react.useState)(decode(
|
|
1249
|
+
const [queryParams, setQueryParams] = (0, react.useState)(decode(alepha, schema, router.query[key]));
|
|
1245
1250
|
(0, react.useEffect)(() => {
|
|
1246
|
-
setQueryParams(decode(
|
|
1251
|
+
setQueryParams(decode(alepha, schema, querystring));
|
|
1247
1252
|
}, [querystring]);
|
|
1248
1253
|
return [queryParams, (queryParams$1) => {
|
|
1249
1254
|
setQueryParams(queryParams$1);
|
|
1250
1255
|
router.setQueryParams((data) => {
|
|
1251
1256
|
return {
|
|
1252
1257
|
...data,
|
|
1253
|
-
[key]: encode(
|
|
1258
|
+
[key]: encode(alepha, schema, queryParams$1)
|
|
1254
1259
|
};
|
|
1255
1260
|
});
|
|
1256
1261
|
}];
|
|
@@ -1269,14 +1274,73 @@ const decode = (alepha, schema, data) => {
|
|
|
1269
1274
|
//#endregion
|
|
1270
1275
|
//#region src/hooks/useRouterState.ts
|
|
1271
1276
|
const useRouterState = () => {
|
|
1272
|
-
const
|
|
1277
|
+
const router = (0, react.useContext)(RouterContext);
|
|
1273
1278
|
const layer = (0, react.useContext)(RouterLayerContext);
|
|
1274
|
-
if (!
|
|
1275
|
-
const [state, setState] = (0, react.useState)(
|
|
1279
|
+
if (!router || !layer) throw new Error("useRouterState must be used within a RouterContext.Provider");
|
|
1280
|
+
const [state, setState] = (0, react.useState)(router.state);
|
|
1276
1281
|
useRouterEvents({ onEnd: ({ state: state$1 }) => setState({ ...state$1 }) });
|
|
1277
1282
|
return state;
|
|
1278
1283
|
};
|
|
1279
1284
|
|
|
1285
|
+
//#endregion
|
|
1286
|
+
//#region src/hooks/useSchema.ts
|
|
1287
|
+
const useSchema = (action) => {
|
|
1288
|
+
const name = action.name;
|
|
1289
|
+
const alepha = useAlepha();
|
|
1290
|
+
const httpClient = useInject(__alepha_server.HttpClient);
|
|
1291
|
+
const linkProvider = useInject(__alepha_server_links.LinkProvider);
|
|
1292
|
+
const [schema, setSchema] = (0, react.useState)(ssrSchemaLoading(alepha, name));
|
|
1293
|
+
(0, react.useEffect)(() => {
|
|
1294
|
+
if (!schema.loading) return;
|
|
1295
|
+
const opts = { cache: true };
|
|
1296
|
+
httpClient.fetch(`${linkProvider.URL_LINKS}/${name}/schema`, {}, opts).then((it) => setSchema(it.data));
|
|
1297
|
+
}, [name]);
|
|
1298
|
+
return schema;
|
|
1299
|
+
};
|
|
1300
|
+
/**
|
|
1301
|
+
* Get an action schema during server-side rendering (SSR) or client-side rendering (CSR).
|
|
1302
|
+
*/
|
|
1303
|
+
const ssrSchemaLoading = (alepha, name) => {
|
|
1304
|
+
if (!alepha.isBrowser()) {
|
|
1305
|
+
const links = alepha.context.get("links")?.links ?? [];
|
|
1306
|
+
const can = links.find((it) => it.name === name);
|
|
1307
|
+
if (can) {
|
|
1308
|
+
const schema$1 = alepha.inject(__alepha_server_links.LinkProvider).links?.find((it) => it.name === name)?.schema;
|
|
1309
|
+
if (schema$1) {
|
|
1310
|
+
can.schema = schema$1;
|
|
1311
|
+
return schema$1;
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
return { loading: true };
|
|
1315
|
+
}
|
|
1316
|
+
const schema = alepha.inject(__alepha_server_links.LinkProvider).links?.find((it) => it.name === name)?.schema;
|
|
1317
|
+
if (schema) return schema;
|
|
1318
|
+
return { loading: true };
|
|
1319
|
+
};
|
|
1320
|
+
|
|
1321
|
+
//#endregion
|
|
1322
|
+
//#region src/hooks/useStore.ts
|
|
1323
|
+
/**
|
|
1324
|
+
* Hook to access and mutate the Alepha state.
|
|
1325
|
+
*/
|
|
1326
|
+
const useStore = (key) => {
|
|
1327
|
+
const alepha = useAlepha();
|
|
1328
|
+
const [state, setState] = (0, react.useState)(alepha.state(key));
|
|
1329
|
+
(0, react.useEffect)(() => {
|
|
1330
|
+
if (!alepha.isBrowser()) return;
|
|
1331
|
+
return alepha.on("state:mutate", (ev) => {
|
|
1332
|
+
if (ev.key === key) setState(ev.value);
|
|
1333
|
+
});
|
|
1334
|
+
}, []);
|
|
1335
|
+
if (!alepha.isBrowser()) {
|
|
1336
|
+
const value = alepha.context.get(key);
|
|
1337
|
+
if (value !== null) return [value, (_) => {}];
|
|
1338
|
+
}
|
|
1339
|
+
return [state, (value) => {
|
|
1340
|
+
alepha.state(key, value);
|
|
1341
|
+
}];
|
|
1342
|
+
};
|
|
1343
|
+
|
|
1280
1344
|
//#endregion
|
|
1281
1345
|
//#region src/index.ts
|
|
1282
1346
|
/**
|
|
@@ -1302,6 +1366,7 @@ const AlephaReact = (0, __alepha_core.$module)({
|
|
|
1302
1366
|
|
|
1303
1367
|
//#endregion
|
|
1304
1368
|
exports.$page = $page;
|
|
1369
|
+
exports.AlephaContext = AlephaContext;
|
|
1305
1370
|
exports.AlephaReact = AlephaReact;
|
|
1306
1371
|
exports.ClientOnly = ClientOnly_default;
|
|
1307
1372
|
exports.ErrorBoundary = ErrorBoundary_default;
|
|
@@ -1317,6 +1382,7 @@ exports.RouterContext = RouterContext;
|
|
|
1317
1382
|
exports.RouterHookApi = RouterHookApi;
|
|
1318
1383
|
exports.RouterLayerContext = RouterLayerContext;
|
|
1319
1384
|
exports.isPageRoute = isPageRoute;
|
|
1385
|
+
exports.ssrSchemaLoading = ssrSchemaLoading;
|
|
1320
1386
|
exports.useActive = useActive;
|
|
1321
1387
|
exports.useAlepha = useAlepha;
|
|
1322
1388
|
exports.useClient = useClient;
|
|
@@ -1325,4 +1391,6 @@ exports.useQueryParams = useQueryParams;
|
|
|
1325
1391
|
exports.useRouter = useRouter;
|
|
1326
1392
|
exports.useRouterEvents = useRouterEvents;
|
|
1327
1393
|
exports.useRouterState = useRouterState;
|
|
1394
|
+
exports.useSchema = useSchema;
|
|
1395
|
+
exports.useStore = useStore;
|
|
1328
1396
|
//# sourceMappingURL=index.cjs.map
|