@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/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 = useAlepha().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 ctx = (0, react.useContext)(RouterContext);
245
- if (!ctx) throw new Error("useRouter must be used within a RouterProvider");
248
+ const alepha = useAlepha();
246
249
  (0, react.useEffect)(() => {
247
- if (!ctx.alepha.isBrowser()) return;
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(ctx.alepha.on("react:transition:begin", { callback: onBegin }));
253
- if (onEnd) subs.push(ctx.alepha.on("react:transition:end", { callback: onEnd }));
254
- if (onError) subs.push(ctx.alepha.on("react:transition:error", { callback: onError }));
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, { error });
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 === location.pathname) return;
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.state("react.server.template") ?? "<!DOCTYPE html><html lang='en'><head></head><body></body></html>";
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 ctx.alepha.inject(PageDescriptorProvider).getPages();
1168
+ return alepha.inject(PageDescriptorProvider).getPages();
1162
1169
  }, []);
1163
- return (0, react.useMemo)(() => new RouterHookApi(pages, ctx.context, ctx.state, layer, ctx.alepha.isBrowser() ? ctx.alepha.inject(ReactBrowserProvider) : void 0), [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 = (clazz) => {
1225
- const ctx = (0, react.useContext)(RouterContext);
1226
- if (!ctx) throw new Error("useRouter must be used within a <RouterProvider>");
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 ctx = (0, react.useContext)(RouterContext);
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(ctx.alepha, schema, router.query[key]));
1249
+ const [queryParams, setQueryParams] = (0, react.useState)(decode(alepha, schema, router.query[key]));
1245
1250
  (0, react.useEffect)(() => {
1246
- setQueryParams(decode(ctx.alepha, schema, querystring));
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(ctx.alepha, schema, queryParams$1)
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 ctx = (0, react.useContext)(RouterContext);
1277
+ const router = (0, react.useContext)(RouterContext);
1273
1278
  const layer = (0, react.useContext)(RouterLayerContext);
1274
- if (!ctx || !layer) throw new Error("useRouter must be used within a RouterProvider");
1275
- const [state, setState] = (0, react.useState)(ctx.state);
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