@alepha/react 0.9.1 → 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.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { $env, $hook, $inject, $logger, $module, Alepha, Descriptor, KIND, NotImplementedError, createDescriptor, t } from "@alepha/core";
2
- import { AlephaServer, ServerRouterProvider, ServerTimingProvider, apiLinksResponseSchema } from "@alepha/server";
2
+ import { AlephaServer, HttpClient, ServerRouterProvider, ServerTimingProvider, apiLinksResponseSchema } from "@alepha/server";
3
3
  import { AlephaServerCache } from "@alepha/server-cache";
4
4
  import { AlephaServerLinks, LinkProvider, ServerLinksProvider } from "@alepha/server-links";
5
5
  import React, { StrictMode, createContext, createElement, useContext, useEffect, useMemo, useState } from "react";
@@ -207,20 +207,31 @@ const RouterContext = createContext(void 0);
207
207
  //#region src/contexts/RouterLayerContext.ts
208
208
  const RouterLayerContext = createContext(void 0);
209
209
 
210
+ //#endregion
211
+ //#region src/contexts/AlephaContext.ts
212
+ const AlephaContext = createContext(void 0);
213
+
214
+ //#endregion
215
+ //#region src/hooks/useAlepha.ts
216
+ const useAlepha = () => {
217
+ const alepha = useContext(AlephaContext);
218
+ if (!alepha) throw new Error("useAlepha must be used within an AlephaContext.Provider");
219
+ return alepha;
220
+ };
221
+
210
222
  //#endregion
211
223
  //#region src/hooks/useRouterEvents.ts
212
224
  const useRouterEvents = (opts = {}, deps = []) => {
213
- const ctx = useContext(RouterContext);
214
- if (!ctx) throw new Error("useRouter must be used within a RouterProvider");
225
+ const alepha = useAlepha();
215
226
  useEffect(() => {
216
- if (!ctx.alepha.isBrowser()) return;
227
+ if (!alepha.isBrowser()) return;
217
228
  const subs = [];
218
229
  const onBegin = opts.onBegin;
219
230
  const onEnd = opts.onEnd;
220
231
  const onError = opts.onError;
221
- if (onBegin) subs.push(ctx.alepha.on("react:transition:begin", { callback: onBegin }));
222
- if (onEnd) subs.push(ctx.alepha.on("react:transition:end", { callback: onEnd }));
223
- if (onError) subs.push(ctx.alepha.on("react:transition:error", { callback: onError }));
232
+ if (onBegin) subs.push(alepha.on("react:transition:begin", { callback: onBegin }));
233
+ if (onEnd) subs.push(alepha.on("react:transition:end", { callback: onEnd }));
234
+ if (onError) subs.push(alepha.on("react:transition:error", { callback: onError }));
224
235
  return () => {
225
236
  for (const sub of subs) sub();
226
237
  };
@@ -360,11 +371,10 @@ var PageDescriptorProvider = class {
360
371
  return new URL(url.replace(/\/\/+/g, "/") || "/", options.base ?? `http://localhost`);
361
372
  }
362
373
  root(state, context) {
363
- const root = createElement(RouterContext.Provider, { value: {
364
- alepha: this.alepha,
374
+ const root = createElement(AlephaContext.Provider, { value: this.alepha }, createElement(RouterContext.Provider, { value: {
365
375
  state,
366
376
  context
367
- } }, createElement(NestedView_default, {}, state.layers[0]?.element));
377
+ } }, createElement(NestedView_default, {}, state.layers[0]?.element)));
368
378
  if (this.env.REACT_STRICT_MODE) return createElement(StrictMode, {}, root);
369
379
  return root;
370
380
  }
@@ -1132,13 +1142,14 @@ var RouterHookApi = class {
1132
1142
  //#endregion
1133
1143
  //#region src/hooks/useRouter.ts
1134
1144
  const useRouter = () => {
1145
+ const alepha = useAlepha();
1135
1146
  const ctx = useContext(RouterContext);
1136
1147
  const layer = useContext(RouterLayerContext);
1137
1148
  if (!ctx || !layer) throw new Error("useRouter must be used within a RouterProvider");
1138
1149
  const pages = useMemo(() => {
1139
- return ctx.alepha.inject(PageDescriptorProvider).getPages();
1150
+ return alepha.inject(PageDescriptorProvider).getPages();
1140
1151
  }, []);
1141
- return useMemo(() => new RouterHookApi(pages, ctx.context, ctx.state, layer, ctx.alepha.isBrowser() ? ctx.alepha.inject(ReactBrowserProvider) : void 0), [layer]);
1152
+ return useMemo(() => new RouterHookApi(pages, ctx.context, ctx.state, layer, alepha.isBrowser() ? alepha.inject(ReactBrowserProvider) : void 0), [layer]);
1142
1153
  };
1143
1154
 
1144
1155
  //#endregion
@@ -1197,20 +1208,11 @@ const useActive = (path) => {
1197
1208
  };
1198
1209
  };
1199
1210
 
1200
- //#endregion
1201
- //#region src/hooks/useAlepha.ts
1202
- const useAlepha = () => {
1203
- const routerContext = useContext(RouterContext);
1204
- if (!routerContext) throw new Error("useAlepha must be used within a RouterProvider");
1205
- return routerContext.alepha;
1206
- };
1207
-
1208
1211
  //#endregion
1209
1212
  //#region src/hooks/useInject.ts
1210
- const useInject = (clazz) => {
1211
- const ctx = useContext(RouterContext);
1212
- if (!ctx) throw new Error("useRouter must be used within a <RouterProvider>");
1213
- return useMemo(() => ctx.alepha.inject(clazz), []);
1213
+ const useInject = (service) => {
1214
+ const alepha = useAlepha();
1215
+ return useMemo(() => alepha.inject(service), []);
1214
1216
  };
1215
1217
 
1216
1218
  //#endregion
@@ -1222,21 +1224,20 @@ const useClient = (_scope) => {
1222
1224
  //#endregion
1223
1225
  //#region src/hooks/useQueryParams.ts
1224
1226
  const useQueryParams = (schema, options = {}) => {
1225
- const ctx = useContext(RouterContext);
1226
- if (!ctx) throw new Error("useQueryParams must be used within a RouterProvider");
1227
+ const alepha = useAlepha();
1227
1228
  const key = options.key ?? "q";
1228
1229
  const router = useRouter();
1229
1230
  const querystring = router.query[key];
1230
- const [queryParams, setQueryParams] = useState(decode(ctx.alepha, schema, router.query[key]));
1231
+ const [queryParams, setQueryParams] = useState(decode(alepha, schema, router.query[key]));
1231
1232
  useEffect(() => {
1232
- setQueryParams(decode(ctx.alepha, schema, querystring));
1233
+ setQueryParams(decode(alepha, schema, querystring));
1233
1234
  }, [querystring]);
1234
1235
  return [queryParams, (queryParams$1) => {
1235
1236
  setQueryParams(queryParams$1);
1236
1237
  router.setQueryParams((data) => {
1237
1238
  return {
1238
1239
  ...data,
1239
- [key]: encode(ctx.alepha, schema, queryParams$1)
1240
+ [key]: encode(alepha, schema, queryParams$1)
1240
1241
  };
1241
1242
  });
1242
1243
  }];
@@ -1255,14 +1256,73 @@ const decode = (alepha, schema, data) => {
1255
1256
  //#endregion
1256
1257
  //#region src/hooks/useRouterState.ts
1257
1258
  const useRouterState = () => {
1258
- const ctx = useContext(RouterContext);
1259
+ const router = useContext(RouterContext);
1259
1260
  const layer = useContext(RouterLayerContext);
1260
- if (!ctx || !layer) throw new Error("useRouter must be used within a RouterProvider");
1261
- const [state, setState] = useState(ctx.state);
1261
+ if (!router || !layer) throw new Error("useRouterState must be used within a RouterContext.Provider");
1262
+ const [state, setState] = useState(router.state);
1262
1263
  useRouterEvents({ onEnd: ({ state: state$1 }) => setState({ ...state$1 }) });
1263
1264
  return state;
1264
1265
  };
1265
1266
 
1267
+ //#endregion
1268
+ //#region src/hooks/useSchema.ts
1269
+ const useSchema = (action) => {
1270
+ const name = action.name;
1271
+ const alepha = useAlepha();
1272
+ const httpClient = useInject(HttpClient);
1273
+ const linkProvider = useInject(LinkProvider);
1274
+ const [schema, setSchema] = useState(ssrSchemaLoading(alepha, name));
1275
+ useEffect(() => {
1276
+ if (!schema.loading) return;
1277
+ const opts = { cache: true };
1278
+ httpClient.fetch(`${linkProvider.URL_LINKS}/${name}/schema`, {}, opts).then((it) => setSchema(it.data));
1279
+ }, [name]);
1280
+ return schema;
1281
+ };
1282
+ /**
1283
+ * Get an action schema during server-side rendering (SSR) or client-side rendering (CSR).
1284
+ */
1285
+ const ssrSchemaLoading = (alepha, name) => {
1286
+ if (!alepha.isBrowser()) {
1287
+ const links = alepha.context.get("links")?.links ?? [];
1288
+ const can = links.find((it) => it.name === name);
1289
+ if (can) {
1290
+ const schema$1 = alepha.inject(LinkProvider).links?.find((it) => it.name === name)?.schema;
1291
+ if (schema$1) {
1292
+ can.schema = schema$1;
1293
+ return schema$1;
1294
+ }
1295
+ }
1296
+ return { loading: true };
1297
+ }
1298
+ const schema = alepha.inject(LinkProvider).links?.find((it) => it.name === name)?.schema;
1299
+ if (schema) return schema;
1300
+ return { loading: true };
1301
+ };
1302
+
1303
+ //#endregion
1304
+ //#region src/hooks/useStore.ts
1305
+ /**
1306
+ * Hook to access and mutate the Alepha state.
1307
+ */
1308
+ const useStore = (key) => {
1309
+ const alepha = useAlepha();
1310
+ const [state, setState] = useState(alepha.state(key));
1311
+ useEffect(() => {
1312
+ if (!alepha.isBrowser()) return;
1313
+ return alepha.on("state:mutate", (ev) => {
1314
+ if (ev.key === key) setState(ev.value);
1315
+ });
1316
+ }, []);
1317
+ if (!alepha.isBrowser()) {
1318
+ const value = alepha.context.get(key);
1319
+ if (value !== null) return [value, (_) => {}];
1320
+ }
1321
+ return [state, (value) => {
1322
+ alepha.state(key, value);
1323
+ }];
1324
+ };
1325
+
1266
1326
  //#endregion
1267
1327
  //#region src/index.ts
1268
1328
  /**
@@ -1287,5 +1347,5 @@ const AlephaReact = $module({
1287
1347
  });
1288
1348
 
1289
1349
  //#endregion
1290
- export { $page, AlephaReact, ClientOnly_default as ClientOnly, ErrorBoundary_default as ErrorBoundary, Link_default as Link, NestedView_default as NestedView, NotFoundPage as NotFound, PageDescriptor, PageDescriptorProvider, ReactBrowserProvider, ReactServerProvider, RedirectionError, RouterContext, RouterHookApi, RouterLayerContext, isPageRoute, useActive, useAlepha, useClient, useInject, useQueryParams, useRouter, useRouterEvents, useRouterState };
1350
+ export { $page, AlephaContext, AlephaReact, ClientOnly_default as ClientOnly, ErrorBoundary_default as ErrorBoundary, Link_default as Link, NestedView_default as NestedView, NotFoundPage as NotFound, PageDescriptor, PageDescriptorProvider, ReactBrowserProvider, ReactServerProvider, RedirectionError, RouterContext, RouterHookApi, RouterLayerContext, isPageRoute, ssrSchemaLoading, useActive, useAlepha, useClient, useInject, useQueryParams, useRouter, useRouterEvents, useRouterState, useSchema, useStore };
1291
1351
  //# sourceMappingURL=index.js.map