@typed/router 0.0.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/Link.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import * as Effect from '@effect/io/Effect';
2
+ import * as Fx from '@typed/fx';
3
+ import { Hole, Placeholder } from '@typed/html';
4
+ import { Router } from './router.js';
5
+ export declare function Link<R = never, E = never, R2 = never>(props: LinkProps<R, E, R2>): Fx.Fx<R | R2 | Router, E, Hole>;
6
+ export interface LinkProps<R, E, R2> {
7
+ readonly href: string;
8
+ readonly label: string | Placeholder<R, E>;
9
+ readonly className?: string;
10
+ readonly onClick?: (event: MouseEvent & {
11
+ currentTarget: HTMLAnchorElement;
12
+ }) => Effect.Effect<R2, never, unknown>;
13
+ }
14
+ //# sourceMappingURL=Link.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../src/Link.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAA;AAC3C,OAAO,KAAK,EAAE,MAAM,WAAW,CAAA;AAC/B,OAAO,EAAsB,IAAI,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEnE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC,wBAAgB,IAAI,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,KAAK,EAAE,EAAE,GAAG,KAAK,EACnD,KAAK,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GACzB,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,CAkBjC;AAED,MAAM,WAAW,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,CACjB,KAAK,EAAE,UAAU,GAAG;QAAE,aAAa,EAAE,iBAAiB,CAAA;KAAE,KACrD,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;CACvC"}
package/dist/Link.js ADDED
@@ -0,0 +1,19 @@
1
+ import * as Effect from '@effect/io/Effect';
2
+ import { EventHandler, html } from '@typed/html';
3
+ import { Router } from './router.js';
4
+ export function Link(props) {
5
+ const clickHandler = (event) => Effect.gen(function* ($) {
6
+ const { currentPath } = yield* $(Router.get);
7
+ yield* $(currentPath.set(props.href));
8
+ if (props.onClick) {
9
+ yield* $(props.onClick(event));
10
+ }
11
+ });
12
+ return html `<a
13
+ class=${props.className}
14
+ href="${props.href}"
15
+ onclick=${EventHandler.preventDefault(clickHandler)}
16
+ >${props.label}</a
17
+ >`;
18
+ }
19
+ //# sourceMappingURL=Link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Link.js","sourceRoot":"","sources":["../src/Link.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAA;AAE3C,OAAO,EAAE,YAAY,EAAE,IAAI,EAAqB,MAAM,aAAa,CAAA;AAEnE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC,MAAM,UAAU,IAAI,CAClB,KAA0B;IAE1B,MAAM,YAAY,GAAG,CAAC,KAAwD,EAAE,EAAE,CAChF,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrB,MAAM,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAE5C,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;QAErC,IAAI,KAAK,CAAC,OAAO,EAAE;YACjB,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAA;SAC/B;IACH,CAAC,CAAC,CAAA;IAEJ,OAAO,IAAI,CAAA;YACD,KAAK,CAAC,SAAS;YACf,KAAK,CAAC,IAAI;cACR,YAAY,CAAC,cAAc,CAAC,YAAY,CAAC;OAChD,KAAK,CAAC,KAAK;IACd,CAAA;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ import * as Layer from '@effect/io/Layer';
2
+ import * as Context from '@typed/context';
3
+ import * as Fx from '@typed/fx';
4
+ import * as html from '@typed/html';
5
+ import * as Path from '@typed/path';
6
+ import * as Route from '@typed/route';
7
+ export interface RouteMatch<R, E, P extends string> {
8
+ readonly route: Route.Route<R, P>;
9
+ readonly layout?: Fx.Fx<R, E, html.Renderable>;
10
+ readonly match: (params: Fx.Fx<never, never, Path.ParamsOf<P>>) => Fx.Fx<R, E, html.Renderable>;
11
+ readonly provideEnvironment: (environment: Context.Context<R>) => RouteMatch<never, E, P>;
12
+ readonly provideService: <S>(tag: Context.Tag<S>, service: S) => RouteMatch<Exclude<R, S>, E, P>;
13
+ readonly provideLayer: <R2, S>(layer: Layer.Layer<R2, never, S>) => RouteMatch<R2 | Exclude<R, S>, E, P>;
14
+ }
15
+ export declare function RouteMatch<R, P extends string, R2, E2, R3, E3>(route: Route.Route<R, P>, match: (params: Fx.Fx<never, never, Path.ParamsOf<P>>) => Fx.Fx<R2, E2, html.Renderable>, layout?: Fx.Fx<R3, E3, html.Renderable>): RouteMatch<R | R2 | R3, E2 | E3, P>;
16
+ //# sourceMappingURL=RouteMatch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RouteMatch.d.ts","sourceRoot":"","sources":["../src/RouteMatch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAA;AAEzC,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,EAAE,MAAM,WAAW,CAAA;AAC/B,OAAO,KAAK,IAAI,MAAM,aAAa,CAAA;AACnC,OAAO,KAAK,IAAI,MAAM,aAAa,CAAA;AACnC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAErC,MAAM,WAAW,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,MAAM;IAChD,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAEjC,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;IAE9C,QAAQ,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;IAE/F,QAAQ,CAAC,kBAAkB,EAAE,CAAC,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IAEzF,QAAQ,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,KAAK,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IAEhG,QAAQ,CAAC,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC,EAC3B,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAC7B,UAAU,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;CAC1C;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAC5D,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EACxB,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,EACxF,MAAM,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,GACtC,UAAU,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CA0BrC"}
@@ -0,0 +1,15 @@
1
+ import { flow } from '@fp-ts/data/Function';
2
+ import * as Fx from '@typed/fx';
3
+ import * as Route from '@typed/route';
4
+ export function RouteMatch(route, match, layout) {
5
+ const routeMatch = {
6
+ route,
7
+ match,
8
+ layout,
9
+ provideEnvironment: (env) => RouteMatch(Route.provideEnvironment(env)(route), flow(match, Fx.provideSomeEnvironment(env)), layout ? Fx.provideEnvironment(env)(layout) : undefined),
10
+ provideService: (tag, service) => RouteMatch(Route.provideService(tag, service)(route), flow(match, Fx.provideService(tag)(service)), layout ? Fx.provideService(tag)(service)(layout) : undefined),
11
+ provideLayer: (layer) => RouteMatch(Route.provideLayer(layer)(route), flow(match, Fx.provideSomeLayer(layer)), layout ? Fx.provideSomeLayer(layer)(layout) : undefined),
12
+ };
13
+ return routeMatch;
14
+ }
15
+ //# sourceMappingURL=RouteMatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RouteMatch.js","sourceRoot":"","sources":["../src/RouteMatch.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAA;AAE3C,OAAO,KAAK,EAAE,MAAM,WAAW,CAAA;AAG/B,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAkBrC,MAAM,UAAU,UAAU,CACxB,KAAwB,EACxB,KAAwF,EACxF,MAAuC;IAEvC,MAAM,UAAU,GAAwC;QACtD,KAAK;QACL,KAAK;QACL,MAAM;QACN,kBAAkB,EAAE,CAAC,GAAG,EAAE,EAAE,CAC1B,UAAU,CACR,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,EACpC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC,EAC3C,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CACxD;QACH,cAAc,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,CAC/B,UAAU,CACR,KAAK,CAAC,cAAc,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,EACzC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,EAC5C,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAC7D;QACH,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE,CACtB,UAAU,CACR,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAChC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,EACvC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CACxD;KACJ,CAAA;IAED,OAAO,UAAU,CAAA;AACnB,CAAC"}
@@ -0,0 +1,38 @@
1
+ import * as Effect from '@effect/io/Effect';
2
+ import * as Layer from '@effect/io/Layer';
3
+ import * as Context from '@typed/context';
4
+ import * as Fx from '@typed/fx';
5
+ import * as html from '@typed/html';
6
+ import * as Path from '@typed/path';
7
+ import * as Route from '@typed/route';
8
+ import { RouteMatch } from './RouteMatch.js';
9
+ import { Redirect, Router } from './router.js';
10
+ export interface RouteMatcher<R = never, E = never> {
11
+ readonly routes: ReadonlyMap<Route.Route<any, any>, RouteMatch<any, any, any>>;
12
+ readonly match: <R2, P extends string, R3, E3>(route: Route.Route<R2, P>, f: (params: Path.ParamsOf<P>) => Fx.Fx<R3, E3, html.Renderable>) => RouteMatcher<R | R2, E | E3>;
13
+ readonly matchFx: <R2, P extends string, R3, E3>(route: Route.Route<R2, P>, f: (params: Fx.Fx<never, never, Path.ParamsOf<P>>) => Fx.Fx<R3, E3, html.Renderable>) => RouteMatcher<R | R2, E | E3>;
14
+ readonly matchEffect: <R2, P extends string, R3, E3>(route: Route.Route<R2, P>, f: (params: Path.ParamsOf<P>) => Effect.Effect<R3, E3, html.Renderable>) => RouteMatcher<R | R2, E | E3>;
15
+ readonly withLayout: <R2, E2>(fx: Fx.Fx<R2, E2, html.Renderable>) => RouteMatcher<R | R2, E | E2>;
16
+ readonly provideEnvironment: <R2>(environment: Context.Context<R2>) => RouteMatcher<Exclude<R, R2>, E>;
17
+ readonly provideService: <R2>(tag: Context.Tag<R2>, service: R2) => RouteMatcher<Exclude<R, R2>, E>;
18
+ readonly provideLayer: <R2, S>(layer: Layer.Layer<R2, never, S>) => RouteMatcher<Exclude<R, S> | R2, E>;
19
+ readonly notFound: <R2, E2, R3 = never, E3 = never>(f: (path: string) => Fx.Fx<R2, E2, html.Renderable>, options?: FallbackOptions<R3, E3>) => Fx.Fx<Router | R | R2 | R3, E | E2 | E3, html.Renderable>;
20
+ readonly notFoundEffect: <R2, E2, R3 = never, E3 = never>(f: (path: string) => Effect.Effect<R2, E2, html.Renderable>, options?: FallbackOptions<R3, E3>) => Fx.Fx<Router | R | R2 | R3, E | E2 | E3, html.Renderable>;
21
+ readonly redirectTo: <R2, P extends string>(route: Route.Route<R2, P>, ...params: [keyof Path.ParamsOf<P>] extends [never] ? [
22
+ {}?
23
+ ] : [(path: string) => Path.ParamsOf<P>]) => Fx.Fx<Router | R | R2, E | Redirect, html.Renderable>;
24
+ /**
25
+ * @internal
26
+ */
27
+ readonly run: Fx.Fx<Router | R, E | Redirect, html.Renderable | null>;
28
+ }
29
+ export interface FallbackOptions<R, E> {
30
+ readonly layout?: Fx.Fx<R, E, html.Renderable>;
31
+ }
32
+ export declare function RouteMatcher<R, E>(routes: RouteMatcher<R, E>['routes']): RouteMatcher<R, E>;
33
+ export declare namespace RouteMatcher {
34
+ const empty: RouteMatcher<never, never>;
35
+ const concat: <R, E, R2, E2>(matcher: RouteMatcher<R, E>, matcher2: RouteMatcher<R2, E2>) => RouteMatcher<R | R2, E | E2>;
36
+ }
37
+ export declare const matchFx: <R2, P extends string, R3, E3>(route: Route.Route<R2, P>, f: (params: Fx.Fx<never, never, Path.PartsToParams<Path.PathToParts<P>, {}> extends infer T ? { readonly [K in keyof T]: Path.PartsToParams<Path.PathToParts<P>, {}>[K]; } : never>) => Fx.Fx<R3, E3, html.Renderable>) => RouteMatcher<R2, E3>, match: <R2, P extends string, R3, E3>(route: Route.Route<R2, P>, f: (params: Path.PartsToParams<Path.PathToParts<P>, {}> extends infer T ? { readonly [K in keyof T]: Path.PartsToParams<Path.PathToParts<P>, {}>[K]; } : never) => Fx.Fx<R3, E3, html.Renderable>) => RouteMatcher<R2, E3>, matchEffect: <R2, P extends string, R3, E3>(route: Route.Route<R2, P>, f: (params: Path.PartsToParams<Path.PathToParts<P>, {}> extends infer T ? { readonly [K in keyof T]: Path.PartsToParams<Path.PathToParts<P>, {}>[K]; } : never) => Effect.Effect<R3, E3, html.Renderable>) => RouteMatcher<R2, E3>;
38
+ //# sourceMappingURL=RouteMatcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RouteMatcher.d.ts","sourceRoot":"","sources":["../src/RouteMatcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ /* eslint-disable @typescript-eslint/ban-types */
2
+ import * as Effect from '@effect/io/Effect';
3
+ import * as Fiber from '@effect/io/Fiber';
4
+ import { pipe } from '@fp-ts/data/Function';
5
+ import * as Option from '@fp-ts/data/Option';
6
+ import * as Fx from '@typed/fx';
7
+ import { RenderContext } from '@typed/html';
8
+ import * as Route from '@typed/route';
9
+ import { RouteMatch } from './RouteMatch.js';
10
+ import { currentPath, redirectTo, Router } from './router.js';
11
+ export function RouteMatcher(routes) {
12
+ const matcher = {
13
+ routes,
14
+ matchFx: (route, f) => RouteMatcher(new Map(routes).set(route, RouteMatch(route, f))),
15
+ match: (route, f) => RouteMatcher(new Map(routes).set(route, RouteMatch(route, Fx.switchMap(f)))),
16
+ matchEffect: (route, f) => RouteMatcher(new Map(routes).set(route, RouteMatch(route, Fx.switchMapEffect(f)))),
17
+ withLayout: (layout) => RouteMatcher(new Map(Array.from(routes).map(([k, match]) => [
18
+ k,
19
+ RouteMatch(match.route, match.match, match.layout ?? layout),
20
+ ]))),
21
+ provideEnvironment: (environment) => RouteMatcher(new Map(Array.from(routes).map(([k, v]) => [k, v.provideEnvironment(environment)]))),
22
+ provideService: (tag, service) => RouteMatcher(new Map(Array.from(routes).map(([k, v]) => [k, v.provideService(tag, service)]))),
23
+ provideLayer: (layer) => RouteMatcher(new Map(Array.from(routes).map(([k, v]) => [k, v.provideLayer(layer)]))),
24
+ notFound: (f, options = {}) => Router.withFx((router) => Fx.gen(function* ($) {
25
+ const { environment } = yield* $(RenderContext.get);
26
+ // Create stable references to the route matchers
27
+ const matchers = Array.from(routes.values()).map((v) => [v, runRouteMatch(router, v)]);
28
+ const renderFallback = pipe(currentPath, Fx.switchMap(f));
29
+ const fallbackMatch = RouteMatch(Route.base, () => renderFallback, options?.layout);
30
+ let previousFiber;
31
+ let previousLayout;
32
+ let previousRender;
33
+ const samplePreviousValues = () => ({
34
+ fiber: previousFiber,
35
+ layout: previousLayout,
36
+ render: previousRender,
37
+ });
38
+ // This function helps us to ensure shared layouts are only rendered once
39
+ // and the outlet content is changed
40
+ const verifyShouldRerender = (match, render) => Effect.gen(function* ($) {
41
+ const previous = samplePreviousValues();
42
+ // Update the previous values
43
+ previousRender = render;
44
+ previousLayout = match.layout;
45
+ previousFiber = undefined;
46
+ // Skip rerendering if the render function is the same
47
+ if (previous.render === render) {
48
+ return Option.none;
49
+ }
50
+ // Interrupt the previous fiber if it exists
51
+ if (previous.fiber) {
52
+ yield* $(Fiber.interrupt(previous.fiber));
53
+ }
54
+ // If we have a layout, we need to render it and use the route outlet.
55
+ if (match.layout) {
56
+ // Render into the route outlet
57
+ previousFiber = yield* $(pipe(render, Fx.observe(router.outlet.set), Effect.forkScoped));
58
+ return Option.some(match.layout);
59
+ }
60
+ // If we don't have a layout, but we did, we need to clear the outlet
61
+ if (previous.layout) {
62
+ yield* $(router.outlet.set(null));
63
+ }
64
+ // Otherwise use the render function directly
65
+ return Option.some(render);
66
+ });
67
+ return pipe(router.currentPath, environment === 'browser' ? Fx.skipRepeats : Fx.take(1), Fx.switchMapEffect((path) => Effect.gen(function* ($) {
68
+ yield* $(Effect.logDebug(`[@typed/router] Matching path: ${path}.`));
69
+ // Attempt to find the best match
70
+ for (const [match, render] of matchers) {
71
+ yield* $(Effect.logDebug(`[@typed/router] Matching against: ${match.route.path}.`));
72
+ const result = yield* $(match.route.match(path));
73
+ if (Option.isSome(result)) {
74
+ yield* $(Effect.logDebug(`[@typed/router] Matched against: ${match.route.path}.`));
75
+ return yield* $(verifyShouldRerender(match, render));
76
+ }
77
+ }
78
+ yield* $(Effect.logDebug(`[@typed/router] Rendering fallback.`));
79
+ // If we didn't find a match, render the not found page
80
+ return yield* $(verifyShouldRerender(fallbackMatch, renderFallback));
81
+ })), Fx.compact, Fx.skipRepeats, // Stable render references are used to avoid mounting the same component twice
82
+ Fx.switchLatest);
83
+ })),
84
+ notFoundEffect: (f) => matcher.notFound((path) => Fx.fromEffect(f(path))),
85
+ redirectTo: ((route, ...params) => matcher.notFound(() => redirectTo.fx(route, ...params))),
86
+ run: Fx.suspend(() => matcher.notFoundEffect(Effect.never)),
87
+ };
88
+ return matcher;
89
+ }
90
+ (function (RouteMatcher) {
91
+ RouteMatcher.empty = RouteMatcher(new Map());
92
+ RouteMatcher.concat = (matcher, matcher2) => RouteMatcher(new Map([...matcher.routes, ...matcher2.routes]));
93
+ })(RouteMatcher || (RouteMatcher = {}));
94
+ export const { matchFx, match, matchEffect } = RouteMatcher(new Map());
95
+ function runRouteMatch(router, { route, match }) {
96
+ return Fx.gen(function* ($) {
97
+ const env = yield* $(Effect.environment());
98
+ const nestedRouter = router.define(route);
99
+ const params = pipe(nestedRouter.params, Fx.provideEnvironment(env));
100
+ return pipe(match(params), Router.provideFx(nestedRouter));
101
+ });
102
+ }
103
+ //# sourceMappingURL=RouteMatcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RouteMatcher.js","sourceRoot":"","sources":["../src/RouteMatcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export * from './router.js';
2
+ export * from './Link.js';
3
+ export * from './RouteMatcher.js';
4
+ export * from './RouteMatch.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export * from './router.js';
2
+ export * from './Link.js';
3
+ export * from './RouteMatcher.js';
4
+ export * from './RouteMatch.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA"}
@@ -0,0 +1,67 @@
1
+ import * as Effect from '@effect/io/Effect';
2
+ import * as Layer from '@effect/io/Layer';
3
+ import * as Scope from '@effect/io/Scope';
4
+ import * as Context from '@typed/context';
5
+ import { Location, History } from '@typed/dom';
6
+ import * as Fx from '@typed/fx';
7
+ import * as html from '@typed/html';
8
+ import { RenderContext } from '@typed/html';
9
+ import * as Path from '@typed/path';
10
+ import * as Route from '@typed/route';
11
+ export interface Router<out R = never, in out P extends string = string> {
12
+ /**
13
+ * The base route the Router is starting from.
14
+ */
15
+ readonly route: Route.Route<R, P>;
16
+ /**
17
+ * The current path of the application
18
+ */
19
+ readonly currentPath: Fx.RefSubject<string>;
20
+ /**
21
+ * The current matched params of the router
22
+ */
23
+ readonly params: Fx.Fx<R, never, Path.ParamsOf<P>>;
24
+ /**
25
+ * The current outlet of this Router
26
+ */
27
+ readonly outlet: Fx.RefSubject<html.Renderable>;
28
+ /**
29
+ * Helper for constructing a path from a route relative to the router.
30
+ */
31
+ readonly createPath: <R2 extends Route.Route<any, string>, P extends Route.ParamsOf<R2>>(route: R2, ...[params]: [keyof P] extends [never] ? [] : [P]) => Effect.Effect<R, never, Path.PathJoin<[
32
+ Path.Interpolate<Route.PathOf<R>, Route.ParamsOf<R>>,
33
+ Path.Interpolate<Route.PathOf<R2>, P>
34
+ ]>>;
35
+ /**
36
+ * Helper for constructing a nested router
37
+ */
38
+ readonly define: <R2, Path2 extends string>(route: Route.Route<R2, Path2>) => Router<R | R2, Path.PathJoin<[P, Path2]>>;
39
+ /**
40
+ * Provide all the resources needed for a Router
41
+ */
42
+ readonly provideEnvironment: (environment: Context.Context<R>) => Router<never, P>;
43
+ }
44
+ export declare const Router: (<R = never, P extends string = string>(route: Route.Route<R, P>, currentPath: Fx.RefSubject<string>) => Router<R, P>) & Context.Tag<Router<never, string>>;
45
+ export declare const outlet: Fx.Fx<RenderContext | Router, never, html.Renderable>;
46
+ export declare const currentPath: Fx.Fx<Router, never, string>;
47
+ export declare function provideEnvironment<R>(environment: Context.Context<R>): <P extends string>(router: Router<R, P>) => Router<never, P>;
48
+ export interface Redirect {
49
+ readonly _tag: 'Redirect';
50
+ readonly path: string;
51
+ }
52
+ export declare namespace Redirect {
53
+ const make: (path: string) => Redirect;
54
+ const is: (r: unknown) => r is Redirect;
55
+ }
56
+ export declare function redirect(path: string): Effect.Effect<never, Redirect, never>;
57
+ export declare namespace redirect {
58
+ var fx: (path: string) => Fx.Fx<never, Redirect, never>;
59
+ }
60
+ export declare const redirectTo: {
61
+ <R, P extends string>(route: Route.Route<R, P>, ...[params]: [keyof Path.PartsToParams<Path.PathToParts<P>, {}>] extends [never] ? [({} | undefined)?] : [Path.PartsToParams<Path.PathToParts<P>, {}> extends infer T ? { readonly [K in keyof T]: Path.PartsToParams<Path.PathToParts<P>, {}>[K]; } : never]): Effect.Effect<Router, Redirect, never>;
62
+ fx<R_1, P_1 extends string>(route: Route.Route<R_1, P_1>, ...params: [keyof Path.PartsToParams<Path.PathToParts<P_1>, {}>] extends [never] ? [({} | undefined)?] : [(path: string) => Path.PartsToParams<Path.PathToParts<P_1>, {}> extends infer T_1 ? { readonly [K_1 in keyof T_1]: Path.PartsToParams<Path.PathToParts<P_1>, {}>[K_1]; } : never]): Fx.Fx<Router, Redirect, never>;
63
+ };
64
+ export declare const makeRouter: (currentPath?: Fx.RefSubject<string>) => Effect.Effect<Location | History | Window | Document | Scope.Scope, never, Router>;
65
+ export declare const live: (currentPath?: Fx.RefSubject<string>) => Layer.Layer<Location | History | Window | Document, never, Router<never, string>>;
66
+ export declare function getCurrentPath(location: Location | HTMLAnchorElement): string;
67
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
package/dist/router.js ADDED
@@ -0,0 +1,123 @@
1
+ /* eslint-disable @typescript-eslint/ban-types */
2
+ import * as Effect from '@effect/io/Effect';
3
+ import { pipe } from '@fp-ts/data/Function';
4
+ import * as Option from '@fp-ts/data/Option';
5
+ import * as Context from '@typed/context';
6
+ import { Location, History, addWindowListener } from '@typed/dom';
7
+ import * as Fx from '@typed/fx';
8
+ import { RenderContext } from '@typed/html';
9
+ import * as Route from '@typed/route';
10
+ export const Router = Object.assign(function makeRouter(route, currentPath) {
11
+ const outlet = Fx.RefSubject.unsafeMake(() => null);
12
+ const createPath = (other, ...[params]) => Effect.gen(function* ($) {
13
+ const path = yield* $(currentPath.get);
14
+ const baseParams = yield* $(route.match(path));
15
+ if (Option.isNone(baseParams)) {
16
+ return yield* $(Effect.dieMessage(`Can not create path when the parent can not be matched.
17
+ Parent Route: ${route.path}
18
+ Current Route: ${other.path}
19
+ Current Path: ${path}`));
20
+ }
21
+ return route.concat(other).make({ ...baseParams.value, ...params });
22
+ });
23
+ const router = {
24
+ route,
25
+ currentPath,
26
+ params: pipe(currentPath, Fx.switchMapEffect(route.match), Fx.compact, Fx.skipRepeats),
27
+ outlet,
28
+ createPath: createPath,
29
+ define: (other) => makeRouter(route.concat(other), currentPath),
30
+ provideEnvironment: (env) => provideEnvironment(env)(router),
31
+ };
32
+ return router;
33
+ }, Context.Tag());
34
+ export const outlet = RenderContext.withFx(({ environment }) => Router.withFx((r) => environment === 'browser'
35
+ ? r.outlet
36
+ : pipe(r.outlet, Fx.skipUntil((x) => x !== null), Fx.take(1))));
37
+ export const currentPath = Router.withFx((r) => r.currentPath);
38
+ export function provideEnvironment(environment) {
39
+ return (router) => {
40
+ const provided = {
41
+ ...router,
42
+ params: pipe(router.params, Fx.provideEnvironment(environment)),
43
+ route: Route.provideEnvironment(environment)(router.route),
44
+ createPath: ((other, ...params) => Effect.provideEnvironment(environment)(router.createPath(other, ...params))),
45
+ provideEnvironment: (env) => provideEnvironment(env)(provided),
46
+ };
47
+ return provided;
48
+ };
49
+ }
50
+ export var Redirect;
51
+ (function (Redirect) {
52
+ Redirect.make = (path) => ({ _tag: 'Redirect', path });
53
+ Redirect.is = (r) => typeof r === 'object' && r !== null && '_tag' in r && r._tag === 'Redirect';
54
+ })(Redirect || (Redirect = {}));
55
+ export function redirect(path) {
56
+ return Effect.fail(Redirect.make(path));
57
+ }
58
+ redirect.fx = (path) => Fx.fail(Redirect.make(path));
59
+ export const redirectTo = (route, ...[params]) => pipe(Router.withEffect((r) => r.createPath(route, params)), Effect.flatMap(redirect));
60
+ redirectTo.fx = (route, ...params) => pipe(Router.withEffect((r) => r.createPath(route, params)), Fx.fromEffect, Fx.switchMap(redirect.fx));
61
+ export const makeRouter = (currentPath) => Effect.gen(function* ($) {
62
+ const history = yield* $(History.get);
63
+ const location = yield* $(Location.get);
64
+ if (!currentPath) {
65
+ currentPath = Fx.RefSubject.unsafeMake(() => getCurrentPath(location));
66
+ }
67
+ // Patch history events to emit an event when the path changes
68
+ const historyEvents = yield* $(patchHistory);
69
+ // Update the current path when events occur:
70
+ // - popstate
71
+ // - hashchange
72
+ // - history events
73
+ yield* $(pipe(Fx.mergeAll(addWindowListener('popstate'), addWindowListener('hashchange'), historyEvents),
74
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
75
+ Fx.switchMapEffect(() => currentPath.set(getCurrentPath(location))), Fx.forkScoped));
76
+ // Listen to path changes and update the current history location, if necessary
77
+ yield* $(pipe(currentPath, Fx.skipRepeats, Fx.observe((path) => Effect.sync(() => {
78
+ if (path !== getCurrentPath(location)) {
79
+ history.pushState({}, '', path);
80
+ }
81
+ })), Effect.forkScoped));
82
+ // Make our base router
83
+ return Router(Route.base, currentPath);
84
+ });
85
+ export const live = (currentPath) => Router.layerSoped(makeRouter(currentPath));
86
+ export function getCurrentPath(location) {
87
+ return location.pathname + location.search + location.hash;
88
+ }
89
+ const patchHistory = Effect.gen(function* ($) {
90
+ const history = yield* $(History.get);
91
+ const historyEvents = Fx.Subject.unsafeMake();
92
+ const runtime = yield* $(Effect.runtime());
93
+ patchHistory_(history, () => runtime.unsafeRun(historyEvents.event()));
94
+ return historyEvents;
95
+ });
96
+ function patchHistory_(history, sendEvent) {
97
+ const pushState = history.pushState.bind(history);
98
+ const replaceState = history.replaceState.bind(history);
99
+ const go = history.go.bind(history);
100
+ const back = history.back.bind(history);
101
+ const forward = history.forward.bind(history);
102
+ history.pushState = function (state, title, url) {
103
+ pushState(state, title, url);
104
+ sendEvent();
105
+ };
106
+ history.replaceState = function (state, title, url) {
107
+ replaceState(state, title, url);
108
+ sendEvent();
109
+ };
110
+ history.go = function (delta) {
111
+ go(delta);
112
+ sendEvent();
113
+ };
114
+ history.back = function () {
115
+ back();
116
+ sendEvent();
117
+ };
118
+ history.forward = function () {
119
+ forward();
120
+ sendEvent();
121
+ };
122
+ }
123
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
package/eslintrc.json ADDED
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": "../../eslintrc.json"
3
+ }
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@typed/router",
3
+ "version": "0.0.2",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.js",
7
+ "typings": "dist/index.d.ts",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ },
14
+ "./*": {
15
+ "import": "./dist/*.js",
16
+ "types": "./dist/*.d.ts"
17
+ },
18
+ "./*.js": {
19
+ "import": "./dist/*.js",
20
+ "types": "./dist/*.d.ts"
21
+ }
22
+ },
23
+ "dependencies": {
24
+ "@effect/io": "~0.0.52",
25
+ "@fp-ts/data": "~0.0.36",
26
+ "@typed/context": "0.0.2",
27
+ "@typed/dom": "8.0.1",
28
+ "@typed/fx": "1.0.1",
29
+ "@typed/html": "3.0.1",
30
+ "@typed/path": "0.0.2",
31
+ "@typed/route": "0.0.2"
32
+ },
33
+ "gitHead": "1d31563070523e63b479cf41b90655b4c9fa641e",
34
+ "publishConfig": {
35
+ "access": "public"
36
+ }
37
+ }
package/project.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
3
+ "projectType": "library",
4
+ "targets": {
5
+ "build": {
6
+ "executor": "nx:run-commands",
7
+ "options": {
8
+ "commands": [
9
+ {
10
+ "command": "tsc --build packages/router/tsconfig.build.json"
11
+ }
12
+ ]
13
+ },
14
+ "outputs": ["{projectRoot}/dist"]
15
+ },
16
+ "lint": {
17
+ "executor": "@nrwl/linter:eslint",
18
+ "options": {
19
+ "lintFilePatterns": ["packages/router/src/**/*.ts"]
20
+ }
21
+ },
22
+ "test": {
23
+ "executor": "@nrwl/vite:test"
24
+ }
25
+ }
26
+ }
package/src/Link.ts ADDED
@@ -0,0 +1,36 @@
1
+ import * as Effect from '@effect/io/Effect'
2
+ import * as Fx from '@typed/fx'
3
+ import { EventHandler, html, Hole, Placeholder } from '@typed/html'
4
+
5
+ import { Router } from './router.js'
6
+
7
+ export function Link<R = never, E = never, R2 = never>(
8
+ props: LinkProps<R, E, R2>,
9
+ ): Fx.Fx<R | R2 | Router, E, Hole> {
10
+ const clickHandler = (event: MouseEvent & { currentTarget: HTMLAnchorElement }) =>
11
+ Effect.gen(function* ($) {
12
+ const { currentPath } = yield* $(Router.get)
13
+
14
+ yield* $(currentPath.set(props.href))
15
+
16
+ if (props.onClick) {
17
+ yield* $(props.onClick(event))
18
+ }
19
+ })
20
+
21
+ return html`<a
22
+ class=${props.className}
23
+ href="${props.href}"
24
+ onclick=${EventHandler.preventDefault(clickHandler)}
25
+ >${props.label}</a
26
+ >`
27
+ }
28
+
29
+ export interface LinkProps<R, E, R2> {
30
+ readonly href: string
31
+ readonly label: string | Placeholder<R, E>
32
+ readonly className?: string
33
+ readonly onClick?: (
34
+ event: MouseEvent & { currentTarget: HTMLAnchorElement },
35
+ ) => Effect.Effect<R2, never, unknown>
36
+ }