kiru 0.51.0-preview.1 → 0.51.0-preview.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/constants.d.ts.map +1 -1
- package/dist/constants.js +1 -0
- package/dist/constants.js.map +1 -1
- package/dist/router/cache.d.ts +71 -0
- package/dist/router/cache.d.ts.map +1 -0
- package/dist/router/cache.js +325 -0
- package/dist/router/cache.js.map +1 -0
- package/dist/router/client/index.d.ts.map +1 -1
- package/dist/router/client/index.js +15 -1
- package/dist/router/client/index.js.map +1 -1
- package/dist/router/context.d.ts +8 -0
- package/dist/router/context.d.ts.map +1 -1
- package/dist/router/context.js.map +1 -1
- package/dist/router/fileRouterController.d.ts +1 -0
- package/dist/router/fileRouterController.d.ts.map +1 -1
- package/dist/router/fileRouterController.js +124 -36
- package/dist/router/fileRouterController.js.map +1 -1
- package/dist/router/globals.d.ts +4 -0
- package/dist/router/globals.d.ts.map +1 -1
- package/dist/router/globals.js +3 -0
- package/dist/router/globals.js.map +1 -1
- package/dist/router/index.d.ts +3 -0
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +6 -0
- package/dist/router/index.js.map +1 -1
- package/dist/router/server/index.d.ts.map +1 -1
- package/dist/router/server/index.js +20 -14
- package/dist/router/server/index.js.map +1 -1
- package/dist/router/types.d.ts +31 -3
- package/dist/router/types.d.ts.map +1 -1
- package/dist/router/types.internal.d.ts +9 -8
- package/dist/router/types.internal.d.ts.map +1 -1
- package/dist/router/utils/index.d.ts +1 -6
- package/dist/router/utils/index.d.ts.map +1 -1
- package/dist/router/utils/index.js +1 -1
- package/dist/router/utils/index.js.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +1 -0
- package/src/router/cache.ts +385 -0
- package/src/router/client/index.ts +18 -1
- package/src/router/context.ts +8 -0
- package/src/router/fileRouterController.ts +140 -47
- package/src/router/globals.ts +5 -0
- package/src/router/index.ts +8 -0
- package/src/router/server/index.ts +30 -14
- package/src/router/types.internal.ts +10 -8
- package/src/router/types.ts +43 -13
- package/src/router/utils/index.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/router/utils/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,sBAAsB,EACtB,UAAU,EACV,aAAa,EACd,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EACL,mBAAmB,EACnB,UAAU,EACV,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,UAAU,EACV,eAAe,GAChB,CAAA;AAED,iBAAS,mBAAmB,CAC1B,GAAG,EAAE,aAAa,EAClB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,GACd,sBAAsB,CAqDxB;AAED,iBAAS,UAAU,CACjB,KAAK,EAAE,sBAAsB,EAC7B,YAAY,EAAE,MAAM,EAAE,GACrB,UAAU,GAAG,IAAI,CA+DnB;AAED,iBAAS,aAAa,CACpB,KAAK,EAAE,sBAAsB,EAC7B,YAAY,EAAE,MAAM,EAAE,GACrB,UAAU,GAAG,IAAI,CAYnB;AAED,iBAAS,YAAY,CACnB,OAAO,EAAE,sBAAsB,EAC/B,aAAa,EAAE,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/router/utils/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,sBAAsB,EACtB,UAAU,EACV,aAAa,EACd,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EACL,mBAAmB,EACnB,UAAU,EACV,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,UAAU,EACV,eAAe,GAChB,CAAA;AAED,iBAAS,mBAAmB,CAC1B,GAAG,EAAE,aAAa,EAClB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,GACd,sBAAsB,CAqDxB;AAED,iBAAS,UAAU,CACjB,KAAK,EAAE,sBAAsB,EAC7B,YAAY,EAAE,MAAM,EAAE,GACrB,UAAU,GAAG,IAAI,CA+DnB;AAED,iBAAS,aAAa,CACpB,KAAK,EAAE,sBAAsB,EAC7B,YAAY,EAAE,MAAM,EAAE,GACrB,UAAU,GAAG,IAAI,CAYnB;AAED,iBAAS,YAAY,CACnB,OAAO,EAAE,sBAAsB,EAC/B,aAAa,EAAE,MAAM,EAAE,iHAYxB;AAED,iBAAS,mBAAmB,CAAC,IAAI,EAAE,MAAM,UAYxC;AAED,iBAAS,UAAU,CACjB,MAAM,EAAE,MAAM,GACb,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAkB/C;AAED,iBAAS,eAAe,CACtB,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE,EAClB,IAAI,EAAE,IAAI,CAAC,EAAE,EACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,cAM/B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/router/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAOtC,OAAO,EACL,mBAAmB,EACnB,UAAU,EACV,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,UAAU,EACV,eAAe,GAChB,CAAA;AAED,SAAS,mBAAmB,CAC1B,GAAkB,EAClB,GAAW,EACX,OAAe;IAEf,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAyB,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAClE,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QACjC,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;YACpB,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,CAAC,IAAI,CACV,wBAAwB,GAAG,0BAA0B,GAAG,IAAI,CAC7D,CAAA;YACH,CAAC;YACD,OAAO,GAAG,CAAA;QACZ,CAAC;QAED,IAAI,WAAW,GAAG,CAAC,CAAA;QACnB,IAAI,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,CAAA;QACxC,OAAO,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAChB,CAAC;QACD,MAAM,QAAQ,GAAa,EAAE,CAAA;QAC7B,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAEvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;YACrB,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClD,IAAI,CAAC,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC3B,MAAM,IAAI,KAAK,CACb,yDAAyD,GAAG,GAAG,CAChE,CAAA;gBACH,CAAC;gBACD,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;gBACvC,WAAW,IAAI,CAAC,CAAA;gBAChB,MAAK;YACP,CAAC;YACD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC/C,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;gBACtC,WAAW,IAAI,EAAE,CAAA;gBACjB,SAAQ;YACV,CAAC;YACD,WAAW,IAAI,GAAG,CAAA;YAClB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACrB,CAAC;QAED,MAAM,KAAK,GAAmC;YAC5C,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC;YACd,WAAW;YACX,QAAQ;YACR,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/router/utils/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/constants.ts
CHANGED
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
import type { PageDataLoaderCacheConfig, RouteParams } from "./types.js"
|
|
2
|
+
|
|
3
|
+
export interface CacheEntry<T = unknown> {
|
|
4
|
+
data: T
|
|
5
|
+
timestamp: number
|
|
6
|
+
ttl: number
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface CacheKey {
|
|
10
|
+
path: string
|
|
11
|
+
params: RouteParams
|
|
12
|
+
query: Record<string, string | string[] | undefined>
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Abstract base class for router cache implementations
|
|
17
|
+
*/
|
|
18
|
+
abstract class BaseCacheStore {
|
|
19
|
+
protected abstract getItem(key: string): CacheEntry | null
|
|
20
|
+
protected abstract setItem(key: string, entry: CacheEntry): void
|
|
21
|
+
public abstract removeItem(key: string): void
|
|
22
|
+
public abstract getAllKeys(): string[]
|
|
23
|
+
public abstract clear(): void
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Generate a cache key from route information
|
|
27
|
+
*/
|
|
28
|
+
protected generateKey(key: CacheKey): string {
|
|
29
|
+
const { path, params, query } = key
|
|
30
|
+
const sortedParams = Object.keys(params)
|
|
31
|
+
.sort()
|
|
32
|
+
.map((k) => `${k}=${params[k]}`)
|
|
33
|
+
.join("&")
|
|
34
|
+
|
|
35
|
+
const sortedQuery = Object.keys(query)
|
|
36
|
+
.sort()
|
|
37
|
+
.map((k) => {
|
|
38
|
+
const value = query[k]
|
|
39
|
+
if (Array.isArray(value)) {
|
|
40
|
+
return `${k}=${value.sort().join(",")}`
|
|
41
|
+
}
|
|
42
|
+
return `${k}=${value}`
|
|
43
|
+
})
|
|
44
|
+
.join("&")
|
|
45
|
+
|
|
46
|
+
return `kiru-cache:${path}?${sortedParams}&${sortedQuery}`
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Get cached data if it exists and hasn't expired
|
|
51
|
+
*/
|
|
52
|
+
get<T>(key: CacheKey): null | { value: T } {
|
|
53
|
+
const cacheKey = this.generateKey(key)
|
|
54
|
+
const entry = this.getItem(cacheKey)
|
|
55
|
+
|
|
56
|
+
if (!entry) {
|
|
57
|
+
return null
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const now = Date.now()
|
|
61
|
+
if (now - entry.timestamp > entry.ttl) {
|
|
62
|
+
this.removeItem(cacheKey)
|
|
63
|
+
return null
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return { value: entry.data as T }
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Set cached data with TTL
|
|
71
|
+
*/
|
|
72
|
+
set<T>(key: CacheKey, data: T, ttl: number): void {
|
|
73
|
+
const cacheKey = this.generateKey(key)
|
|
74
|
+
const entry: CacheEntry<T> = {
|
|
75
|
+
data,
|
|
76
|
+
timestamp: Date.now(),
|
|
77
|
+
ttl,
|
|
78
|
+
}
|
|
79
|
+
this.setItem(cacheKey, entry)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Get cache size for debugging
|
|
84
|
+
*/
|
|
85
|
+
size(): number {
|
|
86
|
+
return this.getAllKeys().length
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* In-memory cache implementation
|
|
92
|
+
*/
|
|
93
|
+
class MemoryCacheStore extends BaseCacheStore {
|
|
94
|
+
private cache = new Map<string, CacheEntry>()
|
|
95
|
+
|
|
96
|
+
protected getItem(key: string): CacheEntry | null {
|
|
97
|
+
return this.cache.get(key) || null
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
protected setItem(key: string, entry: CacheEntry): void {
|
|
101
|
+
this.cache.set(key, entry)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public removeItem(key: string): void {
|
|
105
|
+
this.cache.delete(key)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
public getAllKeys(): string[] {
|
|
109
|
+
return Array.from(this.cache.keys())
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
public clear(): void {
|
|
113
|
+
this.cache.clear()
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* (local|session)Storage cache implementation
|
|
119
|
+
*/
|
|
120
|
+
class StorageCacheStore extends BaseCacheStore {
|
|
121
|
+
private keyPrefix = "kiru-cache:"
|
|
122
|
+
constructor(private storage: Storage) {
|
|
123
|
+
super()
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
protected getItem(key: string): CacheEntry | null {
|
|
127
|
+
try {
|
|
128
|
+
const item = this.storage.getItem(key)
|
|
129
|
+
return item ? JSON.parse(item) : null
|
|
130
|
+
} catch {
|
|
131
|
+
// Handle JSON parse errors or storage unavailable
|
|
132
|
+
return null
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
protected setItem(key: string, entry: CacheEntry): void {
|
|
137
|
+
try {
|
|
138
|
+
this.storage.setItem(key, JSON.stringify(entry))
|
|
139
|
+
} catch {
|
|
140
|
+
// Handle storage quota exceeded or unavailable
|
|
141
|
+
// Silently fail - cache is not critical
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
public removeItem(key: string): void {
|
|
146
|
+
try {
|
|
147
|
+
this.storage.removeItem(key)
|
|
148
|
+
} catch {
|
|
149
|
+
// Silently handle errors
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
public getAllKeys(): string[] {
|
|
154
|
+
try {
|
|
155
|
+
const keys: string[] = []
|
|
156
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
157
|
+
const key = this.storage.key(i)
|
|
158
|
+
if (key && key.startsWith(this.keyPrefix)) {
|
|
159
|
+
keys.push(key)
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return keys
|
|
163
|
+
} catch {
|
|
164
|
+
return []
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
public clear(): void {
|
|
169
|
+
try {
|
|
170
|
+
const keysToRemove = this.getAllKeys()
|
|
171
|
+
keysToRemove.forEach((key) => this.storage.removeItem(key))
|
|
172
|
+
} catch {
|
|
173
|
+
// Silently handle errors
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Main router cache that manages different storage types
|
|
180
|
+
*/
|
|
181
|
+
export class RouterCache {
|
|
182
|
+
private stores = new Map<string, BaseCacheStore>()
|
|
183
|
+
|
|
184
|
+
constructor() {
|
|
185
|
+
// Initialize default stores
|
|
186
|
+
this.stores.set("memory", new MemoryCacheStore())
|
|
187
|
+
this.stores.set("localStorage", new StorageCacheStore(localStorage))
|
|
188
|
+
this.stores.set("sessionStorage", new StorageCacheStore(sessionStorage))
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Get the appropriate cache store for the given config
|
|
193
|
+
*/
|
|
194
|
+
private getStore(config: PageDataLoaderCacheConfig): BaseCacheStore {
|
|
195
|
+
const store = this.stores.get(config.type)
|
|
196
|
+
if (!store) {
|
|
197
|
+
// Fallback to memory cache if type is not supported
|
|
198
|
+
return this.stores.get("memory")!
|
|
199
|
+
}
|
|
200
|
+
return store
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Get cached data if it exists and hasn't expired
|
|
205
|
+
*/
|
|
206
|
+
get<T>(
|
|
207
|
+
key: CacheKey,
|
|
208
|
+
config: PageDataLoaderCacheConfig
|
|
209
|
+
): null | { value: T } {
|
|
210
|
+
const store = this.getStore(config)
|
|
211
|
+
return store.get<T>(key)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Set cached data with TTL
|
|
216
|
+
*/
|
|
217
|
+
set<T>(key: CacheKey, data: T, config: PageDataLoaderCacheConfig): void {
|
|
218
|
+
const store = this.getStore(config)
|
|
219
|
+
store.set(key, data, config.ttl)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Invalidate cache entries by path patterns across all storage types
|
|
224
|
+
* Supports both exact paths ("/users/1") and folder patterns ("/users/[id]")
|
|
225
|
+
*/
|
|
226
|
+
invalidate(...paths: string[]): void {
|
|
227
|
+
// Invalidate across all storage types
|
|
228
|
+
for (const store of this.stores.values()) {
|
|
229
|
+
this.invalidateInStore(store, paths)
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Invalidate cache entries in a specific store
|
|
235
|
+
*/
|
|
236
|
+
private invalidateInStore(store: BaseCacheStore, paths: string[]): void {
|
|
237
|
+
const keysToDelete: string[] = []
|
|
238
|
+
|
|
239
|
+
for (const path of paths) {
|
|
240
|
+
if (this.isPattern(path)) {
|
|
241
|
+
// Folder path pattern - check all cache keys
|
|
242
|
+
for (const cacheKey of store.getAllKeys()) {
|
|
243
|
+
const keyPath = this.extractPathFromCacheKey(cacheKey)
|
|
244
|
+
if (keyPath && this.pathMatchesPattern(keyPath, [path])) {
|
|
245
|
+
keysToDelete.push(cacheKey)
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
} else {
|
|
249
|
+
// Exact path - find all cache keys that match this path
|
|
250
|
+
for (const cacheKey of store.getAllKeys()) {
|
|
251
|
+
const keyPath = this.extractPathFromCacheKey(cacheKey)
|
|
252
|
+
if (keyPath === path) {
|
|
253
|
+
keysToDelete.push(cacheKey)
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Delete all matched keys
|
|
260
|
+
for (const key of keysToDelete) {
|
|
261
|
+
store.removeItem(key)
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Extract the path part from a cache key
|
|
267
|
+
*/
|
|
268
|
+
private extractPathFromCacheKey(cacheKey: string): string | null {
|
|
269
|
+
// Remove the prefix and extract path part
|
|
270
|
+
const withoutPrefix = cacheKey.replace(/^kiru-cache:/, "")
|
|
271
|
+
const pathPart = withoutPrefix.split("?")[0]
|
|
272
|
+
return pathPart || null
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Check if a pattern string contains dynamic segments
|
|
277
|
+
*/
|
|
278
|
+
private isPattern(path: string): boolean {
|
|
279
|
+
return path.includes("[") && path.includes("]")
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Check if a given path matches any of the invalidation patterns
|
|
284
|
+
*/
|
|
285
|
+
pathMatchesPattern(currentPath: string, patterns: string[]): boolean {
|
|
286
|
+
for (const pattern of patterns) {
|
|
287
|
+
if (this.isPattern(pattern)) {
|
|
288
|
+
// Convert pattern to segments and match
|
|
289
|
+
if (this.matchPathPattern(currentPath, pattern)) {
|
|
290
|
+
return true
|
|
291
|
+
}
|
|
292
|
+
} else {
|
|
293
|
+
// Exact path match
|
|
294
|
+
if (currentPath === pattern) {
|
|
295
|
+
return true
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return false
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Match a path against a pattern using segment-by-segment comparison
|
|
304
|
+
* This is more reliable than regex for our use case
|
|
305
|
+
*/
|
|
306
|
+
private matchPathPattern(path: string, pattern: string): boolean {
|
|
307
|
+
const pathSegments = path.split("/").filter(Boolean)
|
|
308
|
+
const patternSegments = pattern.split("/").filter(Boolean)
|
|
309
|
+
|
|
310
|
+
// Handle catchall patterns
|
|
311
|
+
const hasCatchall = patternSegments.some(
|
|
312
|
+
(seg) => seg.startsWith("[...") && seg.endsWith("]")
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
if (hasCatchall) {
|
|
316
|
+
// Find the catchall position
|
|
317
|
+
const catchallIndex = patternSegments.findIndex(
|
|
318
|
+
(seg) => seg.startsWith("[...") && seg.endsWith("]")
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
// Check segments before catchall
|
|
322
|
+
for (let i = 0; i < catchallIndex; i++) {
|
|
323
|
+
if (!this.segmentMatches(pathSegments[i], patternSegments[i])) {
|
|
324
|
+
return false
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Catchall matches remaining segments
|
|
329
|
+
return pathSegments.length >= catchallIndex
|
|
330
|
+
} else {
|
|
331
|
+
// Regular pattern - must have same number of segments
|
|
332
|
+
if (pathSegments.length !== patternSegments.length) {
|
|
333
|
+
return false
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Check each segment
|
|
337
|
+
for (let i = 0; i < pathSegments.length; i++) {
|
|
338
|
+
if (!this.segmentMatches(pathSegments[i], patternSegments[i])) {
|
|
339
|
+
return false
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
return true
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Check if a path segment matches a pattern segment
|
|
349
|
+
*/
|
|
350
|
+
private segmentMatches(pathSegment: string, patternSegment: string): boolean {
|
|
351
|
+
// Dynamic segment [param] matches any value
|
|
352
|
+
if (
|
|
353
|
+
patternSegment.startsWith("[") &&
|
|
354
|
+
patternSegment.endsWith("]") &&
|
|
355
|
+
!patternSegment.startsWith("[...")
|
|
356
|
+
) {
|
|
357
|
+
return pathSegment !== undefined
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// Catchall segment [...param] matches any remaining segments
|
|
361
|
+
if (patternSegment.startsWith("[...") && patternSegment.endsWith("]")) {
|
|
362
|
+
return true
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// Static segment must match exactly
|
|
366
|
+
return pathSegment === patternSegment
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Clear all cached data across all storage types
|
|
371
|
+
*/
|
|
372
|
+
clear(): void {
|
|
373
|
+
for (const store of this.stores.values()) {
|
|
374
|
+
store.clear()
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Get cache size for debugging (memory cache only)
|
|
380
|
+
*/
|
|
381
|
+
size(): number {
|
|
382
|
+
const memoryStore = this.stores.get("memory")
|
|
383
|
+
return memoryStore ? memoryStore.size() : 0
|
|
384
|
+
}
|
|
385
|
+
}
|
|
@@ -11,10 +11,11 @@ import {
|
|
|
11
11
|
} from "../utils/index.js"
|
|
12
12
|
import type { FormattedViteImportMap, PageModule } from "../types.internal"
|
|
13
13
|
import type { FileRouterConfig, FileRouterPreloadConfig } from "../types"
|
|
14
|
-
import { fileRouterInstance, fileRouterRoute } from "../globals.js"
|
|
14
|
+
import { fileRouterInstance, fileRouterRoute, routerCache } from "../globals.js"
|
|
15
15
|
import { FileRouterController } from "../fileRouterController.js"
|
|
16
16
|
import { FileRouterDataLoadError } from "../errors.js"
|
|
17
17
|
import { __DEV__ } from "../../env.js"
|
|
18
|
+
import { RouterCache } from "../cache.js"
|
|
18
19
|
|
|
19
20
|
interface InitClientOptions {
|
|
20
21
|
dir: string
|
|
@@ -24,7 +25,9 @@ interface InitClientOptions {
|
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
export async function initClient(options: InitClientOptions) {
|
|
28
|
+
routerCache.current = new RouterCache()
|
|
27
29
|
const { dir, baseUrl, pages, layouts } = options
|
|
30
|
+
|
|
28
31
|
const config: FileRouterConfig = {
|
|
29
32
|
dir,
|
|
30
33
|
baseUrl,
|
|
@@ -41,6 +44,7 @@ async function preparePreloadConfig(
|
|
|
41
44
|
isStatic404 = false
|
|
42
45
|
): Promise<FileRouterPreloadConfig> {
|
|
43
46
|
let pageProps = {}
|
|
47
|
+
let cacheData: null | { value: unknown } = null
|
|
44
48
|
let url = new URL(window.location.pathname, "http://localhost")
|
|
45
49
|
const pathSegments = url.pathname.split("/").filter(Boolean)
|
|
46
50
|
let routeMatch = matchRoute(options.pages, pathSegments)
|
|
@@ -82,6 +86,18 @@ async function preparePreloadConfig(
|
|
|
82
86
|
: { data: staticProps.data, error: null, loading: false }
|
|
83
87
|
} else if (typeof page.config?.loader?.load === "function") {
|
|
84
88
|
pageProps = { loading: true, data: null, error: null }
|
|
89
|
+
|
|
90
|
+
const loader = page.config.loader
|
|
91
|
+
// Check cache first if caching is enabled
|
|
92
|
+
if (loader.mode !== "static" && loader.cache) {
|
|
93
|
+
const cacheKey = {
|
|
94
|
+
path: window.location.pathname,
|
|
95
|
+
params: routeMatch.params,
|
|
96
|
+
query: parseQuery(url.search),
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
cacheData = routerCache.current!.get(cacheKey, loader.cache)
|
|
100
|
+
}
|
|
85
101
|
}
|
|
86
102
|
|
|
87
103
|
return {
|
|
@@ -93,5 +109,6 @@ async function preparePreloadConfig(
|
|
|
93
109
|
params: routeMatch.params,
|
|
94
110
|
query: parseQuery(url.search),
|
|
95
111
|
route: routeMatch.route,
|
|
112
|
+
cacheData,
|
|
96
113
|
}
|
|
97
114
|
}
|
package/src/router/context.ts
CHANGED
|
@@ -4,6 +4,14 @@ import { useContext } from "../hooks/index.js"
|
|
|
4
4
|
import type { RouteQuery, RouterState } from "./types.js"
|
|
5
5
|
|
|
6
6
|
export interface FileRouterContextType {
|
|
7
|
+
/**
|
|
8
|
+
* Invalidate cached loader data for the given paths
|
|
9
|
+
* @example
|
|
10
|
+
* invalidate("/users", "/posts", "/users/1")
|
|
11
|
+
* // or invalidate based on folder path
|
|
12
|
+
* invalidate("/users/[id]") // (invalidates /users/1, /users/2, etc.)
|
|
13
|
+
*/
|
|
14
|
+
invalidate(...paths: string[]): void
|
|
7
15
|
/**
|
|
8
16
|
* The current router state
|
|
9
17
|
*/
|