intentx-react-router 1.0.3 → 1.0.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 +15 -22
- package/build/core/intentCore.d.ts +6 -4
- package/build/index.esm.js +1 -1
- package/build/index.js +1 -1
- package/build/router/IntentRoute.d.ts +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -56,13 +56,19 @@ npm install intentx-react-router react-router@^7 react-router-dom@^7
|
|
|
56
56
|
## 1. Define intents
|
|
57
57
|
|
|
58
58
|
``` ts
|
|
59
|
-
import { createIntentRouter } from "intentx-react-router"
|
|
59
|
+
import { createIntentRouter, NavigateFn } from "intentx-react-router"
|
|
60
60
|
|
|
61
61
|
createIntentRouter({
|
|
62
62
|
"view-user": "/users/:userId/name/:page",
|
|
63
63
|
"edit-user": "/users/:userId/edit",
|
|
64
64
|
"checkout": "/checkout"
|
|
65
65
|
})
|
|
66
|
+
|
|
67
|
+
// Bind navigate in App
|
|
68
|
+
export function bindRouterNavigate(navigate: NavigateFn) {
|
|
69
|
+
bindNavigate(navigate);
|
|
70
|
+
}
|
|
71
|
+
|
|
66
72
|
```
|
|
67
73
|
|
|
68
74
|
---
|
|
@@ -75,9 +81,14 @@ import { useNavigate } from "react-router-dom"
|
|
|
75
81
|
import { bindNavigate } from "intentx-react-router"
|
|
76
82
|
|
|
77
83
|
export function RouterBinder() {
|
|
78
|
-
const navigate = useNavigate()
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
const navigate = useNavigate();
|
|
85
|
+
|
|
86
|
+
React.useEffect(() => {
|
|
87
|
+
// require
|
|
88
|
+
bindRouterNavigate(navigate);
|
|
89
|
+
}, [navigate]);
|
|
90
|
+
|
|
91
|
+
return null;
|
|
81
92
|
}
|
|
82
93
|
```
|
|
83
94
|
---
|
|
@@ -114,24 +125,6 @@ export default function App() {
|
|
|
114
125
|
)
|
|
115
126
|
}
|
|
116
127
|
```
|
|
117
|
-
|
|
118
|
-
## 4. IntentRouter
|
|
119
|
-
|
|
120
|
-
```ts
|
|
121
|
-
import { IntentRouter } from "intentx-react-router"
|
|
122
|
-
import { Routes } from "react-router-dom"
|
|
123
|
-
|
|
124
|
-
export default function App() {
|
|
125
|
-
return (
|
|
126
|
-
<IntentRouter>
|
|
127
|
-
<Routes>
|
|
128
|
-
<IntentRoute intent="checkout" component={CheckoutPage} />
|
|
129
|
-
</Routes>
|
|
130
|
-
</IntentRouter>
|
|
131
|
-
)
|
|
132
|
-
}
|
|
133
|
-
```
|
|
134
|
-
|
|
135
128
|
---
|
|
136
129
|
|
|
137
130
|
# Navigation
|
|
@@ -7,12 +7,14 @@ export type NavigateIntentOptions<P = any> = {
|
|
|
7
7
|
scrollTop?: boolean;
|
|
8
8
|
};
|
|
9
9
|
};
|
|
10
|
-
type
|
|
11
|
-
type GuardFn = (intent: string, params: any) => boolean | string | void;
|
|
12
|
-
type NavigateFn = (path: string, options?: {
|
|
10
|
+
export type NavigateOptions = {
|
|
13
11
|
replace?: boolean;
|
|
14
12
|
scrollTop?: boolean;
|
|
15
|
-
|
|
13
|
+
[key: string]: any;
|
|
14
|
+
};
|
|
15
|
+
type IntentMap = Record<string, string>;
|
|
16
|
+
type GuardFn = (intent: string, params: any) => boolean | string | void;
|
|
17
|
+
export type NavigateFn = (path: string, options?: NavigateOptions) => void;
|
|
16
18
|
type PreloadFn = () => Promise<any> | void;
|
|
17
19
|
export declare function createIntentRouter(map: IntentMap): void;
|
|
18
20
|
export declare function bindNavigate(fn: NavigateFn): void;
|
package/build/index.esm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createEventBus as n}from"eventbus-z";import{jsx as t,Fragment as o,jsxs as r}from"react/jsx-runtime";import{Link as e,useLocation as i,useNavigate as c,BrowserRouter as u}from"react-router-dom";import{useEffect as s}from"react";const a=n();let f=null;let l={},p=null,m=!1;const d=[],h={},T={};let y=null;const E="undefined"!=typeof window&&!0===window.__INTENT_ROUTER_DEBUG__;function A(...n){E&&console.log("[IntentRouter]",...n)}function N(n){if(!n)return"";const t=new URLSearchParams;for(const o in n){const r=n[o];null!=r&&(Array.isArray(r)?r.forEach(n=>t.append(o,String(n))):t.append(o,String(r)))}const o=t.toString();return o?`?${o}`:""}function w(n){l=n,A("intent map loaded",n)}function I(n){p&&p!==n&&E&&console.warn("IntentRouter navigate replaced"),p
|
|
1
|
+
import{createEventBus as n}from"eventbus-z";import{jsx as t,Fragment as o,jsxs as r}from"react/jsx-runtime";import{Link as e,useLocation as i,useNavigate as c,BrowserRouter as u}from"react-router-dom";import{useEffect as s}from"react";const a=n();let f=null;let l={},p=null,m=!1;const d=[],h={},T={};let y=null;const E="undefined"!=typeof window&&!0===window.__INTENT_ROUTER_DEBUG__;function A(...n){E&&console.log("[IntentRouter]",...n)}function N(n){if(!n)return"";const t=new URLSearchParams;for(const o in n){const r=n[o];null!=r&&(Array.isArray(r)?r.forEach(n=>t.append(o,String(n))):t.append(o,String(r)))}const o=t.toString();return o?`?${o}`:""}function w(n){l=n,A("intent map loaded",n)}function I(n){p&&p!==n&&E&&console.warn("IntentRouter navigate replaced"),p=n,m||(a.$onMultiple("INTENT_NAVIGATE",G),m=!0)}function g(n){y=n}function _(n,t,o,r){A("emit",n,{params:t,query:o});const e={intent:n,params:t,query:o,...r?{options:r}:{}};a.$emit("INTENT_NAVIGATE",e),f&&f.$emit("INTENT_NAVIGATE",e)}function $(n,t){const{params:o,query:r,options:e}=t||{};A("emit",n,{params:o,query:r});const i={intent:n,params:o,query:r,...e?{options:e}:{}};a.$emit("INTENT_NAVIGATE",i),f&&f.$emit("INTENT_NAVIGATE",i)}function q(n){d.push(n)}function v(n,t){h[n]||(h[n]=[]),h[n].push(t)}function R(n,t){T[n]||(T[n]=[]),T[n].push(t)}function k(n){S(n)}async function G(n){const t=l[n.intent];if(A("receive",n.intent,n),!t)return y&&p?.(y),void console.warn("Unknown intent:",n.intent);const o=V(t,n.params);for(const t of d){const r=await t(n.intent,o);if(!1===r)return;if("string"==typeof r)return void p?.(r,n.options)}const r=h[n.intent]||[];for(const t of r){const r=await t(n.intent,o);if(!1===r)return;if("string"==typeof r)return void p?.(r,n.options)}S(n.intent);const e=P(t,o)+N(n.query);A("navigate",{intent:n.intent,params:o,query:n.query,url:e}),p?.(e,n.options),f&&f.$emit("INTENT_NAVIGATE",n)}function S(n){const t=T[n];if(t)for(const o of t)try{const t=o();t instanceof Promise&&t.catch(()=>{console.warn(`Preload for intent "${n}" failed`)})}catch(t){console.warn(`Preload for intent "${n}" sync error`,t)}}const U={};function V(n,t){const o=function(n){if(U[n])return U[n];const t=[];return n.replace(/:([A-Za-z0-9_]+)/g,(n,o)=>(t.push(o),"")),U[n]=t,t}(n);if(!t)return{};if(Array.isArray(t)){const n={};return o.forEach((o,r)=>{void 0===t[r]&&console.warn(`Missing param "${o}"`),n[o]=t[r]}),n}return"object"==typeof t?t:1===o.length?{[o[0]]:t}:{}}function P(n,t){return n.replace(/:([A-Za-z0-9_]+)/g,(n,o)=>{const r=t[o];return void 0!==r?encodeURIComponent(r):""})}function x(n,t,o){const r=l[n];if(!r)return"";return P(r,V(r,t))+N(o)}const M={};function z(n){if(M[n])return M[n];const t=[],o=new RegExp("^"+n.replace(/:([A-Za-z0-9_]+)/g,(n,o)=>(t.push(o),"([^/]+)"))+"$");return M[n]={regex:o,keys:t},M[n]}function C(n){const[t,o]=n.split("?"),r=function(n){if(!n)return{};const t=new URLSearchParams(n),o={};return t.forEach((n,t)=>{o[t]?Array.isArray(o[t])?o[t].push(n):o[t]=[o[t],n]:o[t]=n}),o}(o);for(const n in l){const o=l[n],{regex:e,keys:i}=z(o),c=t.match(e);if(!c)continue;const u={};return i.forEach((n,t)=>{u[n]=decodeURIComponent(c[t+1])}),{intent:n,params:u,query:r}}return null}function L(n){f=n,f.$onMultiple("INTENT_NAVIGATE",G)}function b({intent:n,params:r,query:i,scrollTop:c,prefetch:u,onClick:s,onMouseEnter:a,onTouchStart:f,...l}){const p=x(n,r,i);return p?t(e,{to:p,onClick:n=>{c&&window.scrollTo({top:0}),s?.(n)},onMouseEnter:t=>{u&&k(n),a?.(t)},onTouchStart:t=>{u&&k(n),f?.(t)},...l}):(console.warn("IntentLink: unknown intent",n),t(o,{children:l.children}))}function Z(){const n=i(),t=C(n.pathname),o=new URLSearchParams(n.search),r={};return o.forEach((n,t)=>{r[t]=n}),{intent:t?.intent??null,params:t?.params??{},query:r}}function j({intent:n,component:r,fallback:e=null,loading:i,guard:c}){const u=Z();return u?u.intent!==n?null:c&&!c(u)?t(o,{children:e}):t(r,{...u}):i?t(o,{children:i}):null}function B({navigate:n}){const t=c();return s(()=>{I(n??t)},[n,t]),null}function D({children:n}){return r(u,{children:[t(B,{}),n]})}function O(n){const t=c();return s(()=>{I(n??t)},[n,t]),_}export{b as IntentLink,j as IntentRoute,D as IntentRouter,B as RouterBinder,q as addIntentGuard,v as addIntentGuardFor,R as addIntentPreload,I as bindNavigate,w as createIntentRouter,x as generatePathFromIntent,_ as navigateIntent,$ as navigateIntentObject,k as preloadIntent,C as resolveIntentFromUrl,g as setFallbackPath,L as setSharedBus,Z as useIntentRouter,O as useNavigateIntent};
|
package/build/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var n=require("eventbus-z"),t=require("react/jsx-runtime"),e=require("react-router-dom"),r=require("react");const o=n.createEventBus();let i=null;let s={},c=null,a=!1;const u=[],f={},l={};let p=null;const d="undefined"!=typeof window&&!0===window.__INTENT_ROUTER_DEBUG__;function m(...n){d&&console.log("[IntentRouter]",...n)}function I(n){if(!n)return"";const t=new URLSearchParams;for(const e in n){const r=n[e];null!=r&&(Array.isArray(r)?r.forEach(n=>t.append(e,String(n))):t.append(e,String(r)))}const e=t.toString();return e?`?${e}`:""}function h(n){c&&c!==n&&d&&console.warn("IntentRouter navigate replaced"),c
|
|
1
|
+
"use strict";var n=require("eventbus-z"),t=require("react/jsx-runtime"),e=require("react-router-dom"),r=require("react");const o=n.createEventBus();let i=null;let s={},c=null,a=!1;const u=[],f={},l={};let p=null;const d="undefined"!=typeof window&&!0===window.__INTENT_ROUTER_DEBUG__;function m(...n){d&&console.log("[IntentRouter]",...n)}function I(n){if(!n)return"";const t=new URLSearchParams;for(const e in n){const r=n[e];null!=r&&(Array.isArray(r)?r.forEach(n=>t.append(e,String(n))):t.append(e,String(r)))}const e=t.toString();return e?`?${e}`:""}function h(n){c&&c!==n&&d&&console.warn("IntentRouter navigate replaced"),c=n,a||(o.$onMultiple("INTENT_NAVIGATE",E),a=!0)}function g(n,t,e,r){m("emit",n,{params:t,query:e});const s={intent:n,params:t,query:e,...r?{options:r}:{}};o.$emit("INTENT_NAVIGATE",s),i&&i.$emit("INTENT_NAVIGATE",s)}function x(n){T(n)}async function E(n){const t=s[n.intent];if(m("receive",n.intent,n),!t)return p&&c?.(p),void console.warn("Unknown intent:",n.intent);const e=y(t,n.params);for(const t of u){const r=await t(n.intent,e);if(!1===r)return;if("string"==typeof r)return void c?.(r,n.options)}const r=f[n.intent]||[];for(const t of r){const r=await t(n.intent,e);if(!1===r)return;if("string"==typeof r)return void c?.(r,n.options)}T(n.intent);const o=A(t,e)+I(n.query);m("navigate",{intent:n.intent,params:e,query:n.query,url:o}),c?.(o,n.options),i&&i.$emit("INTENT_NAVIGATE",n)}function T(n){const t=l[n];if(t)for(const e of t)try{const t=e();t instanceof Promise&&t.catch(()=>{console.warn(`Preload for intent "${n}" failed`)})}catch(t){console.warn(`Preload for intent "${n}" sync error`,t)}}const N={};function y(n,t){const e=function(n){if(N[n])return N[n];const t=[];return n.replace(/:([A-Za-z0-9_]+)/g,(n,e)=>(t.push(e),"")),N[n]=t,t}(n);if(!t)return{};if(Array.isArray(t)){const n={};return e.forEach((e,r)=>{void 0===t[r]&&console.warn(`Missing param "${e}"`),n[e]=t[r]}),n}return"object"==typeof t?t:1===e.length?{[e[0]]:t}:{}}function A(n,t){return n.replace(/:([A-Za-z0-9_]+)/g,(n,e)=>{const r=t[e];return void 0!==r?encodeURIComponent(r):""})}function w(n,t,e){const r=s[n];if(!r)return"";return A(r,y(r,t))+I(e)}const v={};function R(n){if(v[n])return v[n];const t=[],e=new RegExp("^"+n.replace(/:([A-Za-z0-9_]+)/g,(n,e)=>(t.push(e),"([^/]+)"))+"$");return v[n]={regex:e,keys:t},v[n]}function _(n){const[t,e]=n.split("?"),r=function(n){if(!n)return{};const t=new URLSearchParams(n),e={};return t.forEach((n,t)=>{e[t]?Array.isArray(e[t])?e[t].push(n):e[t]=[e[t],n]:e[t]=n}),e}(e);for(const n in s){const e=s[n],{regex:o,keys:i}=R(e),c=t.match(o);if(!c)continue;const a={};return i.forEach((n,t)=>{a[n]=decodeURIComponent(c[t+1])}),{intent:n,params:a,query:r}}return null}function q(){const n=e.useLocation(),t=_(n.pathname),r=new URLSearchParams(n.search),o={};return r.forEach((n,t)=>{o[t]=n}),{intent:t?.intent??null,params:t?.params??{},query:o}}function $({navigate:n}){const t=e.useNavigate();return r.useEffect(()=>{h(n??t)},[n,t]),null}exports.IntentLink=function({intent:n,params:r,query:o,scrollTop:i,prefetch:s,onClick:c,onMouseEnter:a,onTouchStart:u,...f}){const l=w(n,r,o);return l?t.jsx(e.Link,{to:l,onClick:n=>{i&&window.scrollTo({top:0}),c?.(n)},onMouseEnter:t=>{s&&x(n),a?.(t)},onTouchStart:t=>{s&&x(n),u?.(t)},...f}):(console.warn("IntentLink: unknown intent",n),t.jsx(t.Fragment,{children:f.children}))},exports.IntentRoute=function({intent:n,component:e,fallback:r=null,loading:o,guard:i}){const s=q();return s?s.intent!==n?null:i&&!i(s)?t.jsx(t.Fragment,{children:r}):t.jsx(e,{...s}):o?t.jsx(t.Fragment,{children:o}):null},exports.IntentRouter=function({children:n}){return t.jsxs(e.BrowserRouter,{children:[t.jsx($,{}),n]})},exports.RouterBinder=$,exports.addIntentGuard=function(n){u.push(n)},exports.addIntentGuardFor=function(n,t){f[n]||(f[n]=[]),f[n].push(t)},exports.addIntentPreload=function(n,t){l[n]||(l[n]=[]),l[n].push(t)},exports.bindNavigate=h,exports.createIntentRouter=function(n){s=n,m("intent map loaded",n)},exports.generatePathFromIntent=w,exports.navigateIntent=g,exports.navigateIntentObject=function(n,t){const{params:e,query:r,options:s}=t||{};m("emit",n,{params:e,query:r});const c={intent:n,params:e,query:r,...s?{options:s}:{}};o.$emit("INTENT_NAVIGATE",c),i&&i.$emit("INTENT_NAVIGATE",c)},exports.preloadIntent=x,exports.resolveIntentFromUrl=_,exports.setFallbackPath=function(n){p=n},exports.setSharedBus=function(n){i=n,i.$onMultiple("INTENT_NAVIGATE",E)},exports.useIntentRouter=q,exports.useNavigateIntent=function(n){const t=e.useNavigate();return r.useEffect(()=>{h(n??t)},[n,t]),g};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { type IntentData } from "./useIntentRouter";
|
|
1
2
|
type Props = {
|
|
2
3
|
intent: string;
|
|
3
4
|
component: React.ComponentType<any>;
|
|
4
5
|
fallback?: React.ReactNode;
|
|
5
6
|
loading?: React.ReactNode;
|
|
6
|
-
guard?: (data:
|
|
7
|
+
guard?: (data: IntentData) => boolean;
|
|
7
8
|
};
|
|
8
9
|
export declare function IntentRoute({ intent, component: Component, fallback, loading, guard, }: Props): JSX.Element | null;
|
|
9
10
|
export {};
|