@timber-js/app 0.2.0-alpha.80 → 0.2.0-alpha.81
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/_chunks/{stale-reload-C2plcNtG.js → stale-reload-BX5gL1r-.js} +1 -1
- package/dist/_chunks/{stale-reload-C2plcNtG.js.map → stale-reload-BX5gL1r-.js.map} +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/client/form.d.ts +2 -2
- package/dist/client/form.d.ts.map +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.js +1 -1
- package/dist/config-types.d.ts +17 -0
- package/dist/config-types.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +40 -3
- package/dist/index.js.map +1 -1
- package/dist/plugin-context.d.ts +23 -0
- package/dist/plugin-context.d.ts.map +1 -1
- package/dist/search-params/index.js +62 -1
- package/dist/search-params/index.js.map +1 -0
- package/dist/segment-params/index.d.ts +0 -3
- package/dist/segment-params/index.d.ts.map +1 -1
- package/dist/segment-params/index.js +1 -3
- package/dist/server/action-client.d.ts +14 -6
- package/dist/server/action-client.d.ts.map +1 -1
- package/dist/server/index.d.ts +0 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -2
- package/dist/server/index.js.map +1 -1
- package/package.json +5 -1
- package/src/cli.ts +10 -5
- package/src/client/form.tsx +8 -6
- package/src/config-types.ts +17 -0
- package/src/index.ts +37 -0
- package/src/plugin-context.ts +40 -0
- package/src/plugins/adapter-build.ts +1 -1
- package/src/segment-params/index.ts +3 -23
- package/src/server/action-client.ts +26 -10
- package/src/server/index.ts +2 -3
- package/dist/_chunks/wrappers-_DTmImGt.js +0 -63
- package/dist/_chunks/wrappers-_DTmImGt.js.map +0 -1
package/src/index.ts
CHANGED
|
@@ -43,6 +43,8 @@ import {
|
|
|
43
43
|
mergeFileConfig,
|
|
44
44
|
resolveAppDir,
|
|
45
45
|
resolveClientJavascript,
|
|
46
|
+
resolveBuildDir,
|
|
47
|
+
DEFAULT_BUILD_DIR,
|
|
46
48
|
} from './plugin-context.js';
|
|
47
49
|
|
|
48
50
|
// ── Public API ────────────────────────────────────────────────────────────
|
|
@@ -247,6 +249,15 @@ export function timber(config?: TimberUserConfig): PluginOption[] {
|
|
|
247
249
|
ctx.config.output ??= 'server';
|
|
248
250
|
ctx.timer.end('config-load');
|
|
249
251
|
|
|
252
|
+
// ── Resolve build output directory ─────────────────────────
|
|
253
|
+
// Priority: timber.config.ts `buildDir` > Vite `build.outDir` > .timber/dist
|
|
254
|
+
// Set Vite's build.outDir so the RSC plugin and all environment
|
|
255
|
+
// builds write to the correct location.
|
|
256
|
+
const viteOutDir = userConfig.build?.outDir;
|
|
257
|
+
const timberBuildDir = ctx.config.buildDir;
|
|
258
|
+
const resolvedRoot = resolve(userConfig.root ?? process.cwd());
|
|
259
|
+
ctx.buildDir = resolveBuildDir(resolvedRoot, timberBuildDir, viteOutDir);
|
|
260
|
+
|
|
250
261
|
// Warn if the Vite root differs from cwd and the re-loaded config
|
|
251
262
|
// has reactCompiler but the early cwd-based load missed it. In this
|
|
252
263
|
// edge case the user must move reactCompiler to inline config.
|
|
@@ -308,8 +319,28 @@ export function timber(config?: TimberUserConfig): PluginOption[] {
|
|
|
308
319
|
}
|
|
309
320
|
}
|
|
310
321
|
|
|
322
|
+
// Return the resolved buildDir as Vite's build.outDir so the RSC
|
|
323
|
+
// plugin and all environment builds write to the correct location.
|
|
324
|
+
// This is always set — either from timber config, Vite config, or default.
|
|
325
|
+
const buildOutDir = timberBuildDir
|
|
326
|
+
? timberBuildDir
|
|
327
|
+
: viteOutDir && viteOutDir !== 'dist'
|
|
328
|
+
? viteOutDir
|
|
329
|
+
: DEFAULT_BUILD_DIR;
|
|
330
|
+
|
|
331
|
+
// Set per-environment build.outDir so Vite's RSC plugin writes
|
|
332
|
+
// each environment to the correct subdirectory under our buildDir.
|
|
333
|
+
// Without this, the RSC plugin defaults to dist/<envName> instead
|
|
334
|
+
// of <buildOutDir>/<envName>.
|
|
335
|
+
const envOutDirs: Record<string, { build: { outDir: string } }> = {};
|
|
336
|
+
for (const envName of ['rsc', 'ssr', 'client']) {
|
|
337
|
+
envOutDirs[envName] = { build: { outDir: join(buildOutDir, envName) } };
|
|
338
|
+
}
|
|
339
|
+
|
|
311
340
|
if (command === 'build') {
|
|
312
341
|
return {
|
|
342
|
+
build: { outDir: buildOutDir },
|
|
343
|
+
environments: envOutDirs,
|
|
313
344
|
oxc: {
|
|
314
345
|
jsx: {
|
|
315
346
|
development: false,
|
|
@@ -317,11 +348,17 @@ export function timber(config?: TimberUserConfig): PluginOption[] {
|
|
|
317
348
|
},
|
|
318
349
|
};
|
|
319
350
|
}
|
|
351
|
+
|
|
352
|
+
// Dev mode: set outDir so dev-time references are consistent
|
|
353
|
+
return { build: { outDir: buildOutDir }, environments: envOutDirs };
|
|
320
354
|
},
|
|
321
355
|
configResolved(resolved) {
|
|
322
356
|
ctx.root = resolved.root;
|
|
323
357
|
ctx.appDir = resolveAppDir(resolved.root, ctx.config.appDir);
|
|
324
358
|
ctx.dev = resolved.command === 'serve';
|
|
359
|
+
// Sync buildDir from Vite's resolved build.outDir. Vite keeps
|
|
360
|
+
// outDir as-is (may be relative), so resolve against root.
|
|
361
|
+
ctx.buildDir = resolve(resolved.root, resolved.build.outDir);
|
|
325
362
|
// In production builds, swap to a no-op timer to avoid overhead
|
|
326
363
|
if (!ctx.dev) {
|
|
327
364
|
ctx.timer = createNoopTimer();
|
package/src/plugin-context.ts
CHANGED
|
@@ -77,6 +77,16 @@ export interface PluginContext {
|
|
|
77
77
|
timer: StartupTimer;
|
|
78
78
|
/** Holding server that binds the port during dev startup (closed in timber-dev-server) */
|
|
79
79
|
holdingServer?: HoldingServer | null;
|
|
80
|
+
/**
|
|
81
|
+
* Resolved absolute path to the build output directory.
|
|
82
|
+
*
|
|
83
|
+
* Defaults to `<root>/.timber/dist`. Can be overridden via
|
|
84
|
+
* `timber.config.ts` `buildDir` or Vite's `build.outDir`.
|
|
85
|
+
* Timber config takes precedence when both are set.
|
|
86
|
+
*
|
|
87
|
+
* Used by adapter-build and cli preview.
|
|
88
|
+
*/
|
|
89
|
+
buildDir: string;
|
|
80
90
|
}
|
|
81
91
|
|
|
82
92
|
// ── App directory resolution ──────────────────────────────────────────────
|
|
@@ -126,9 +136,39 @@ export function createPluginContext(config?: TimberUserConfig, root?: string): P
|
|
|
126
136
|
deploymentId: null,
|
|
127
137
|
timer: createStartupTimer(),
|
|
128
138
|
holdingServer: null,
|
|
139
|
+
buildDir: resolveBuildDir(projectRoot, resolvedConfig.buildDir),
|
|
129
140
|
};
|
|
130
141
|
}
|
|
131
142
|
|
|
143
|
+
// ── Build directory resolution ────────────────────────────────────────────
|
|
144
|
+
|
|
145
|
+
/** Default build output directory (relative to root). */
|
|
146
|
+
export const DEFAULT_BUILD_DIR = join('.timber', 'dist');
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Resolve the build output directory.
|
|
150
|
+
*
|
|
151
|
+
* Priority:
|
|
152
|
+
* 1. Explicit `timberBuildDir` from timber.config.ts
|
|
153
|
+
* 2. Explicit `viteBuildOutDir` from Vite's build.outDir (if not the default 'dist')
|
|
154
|
+
* 3. Default: `.timber/dist`
|
|
155
|
+
*
|
|
156
|
+
* Returns an absolute path.
|
|
157
|
+
*/
|
|
158
|
+
export function resolveBuildDir(
|
|
159
|
+
root: string,
|
|
160
|
+
timberBuildDir?: string,
|
|
161
|
+
viteBuildOutDir?: string
|
|
162
|
+
): string {
|
|
163
|
+
if (timberBuildDir) {
|
|
164
|
+
return join(root, timberBuildDir);
|
|
165
|
+
}
|
|
166
|
+
if (viteBuildOutDir && viteBuildOutDir !== 'dist') {
|
|
167
|
+
return join(root, viteBuildOutDir);
|
|
168
|
+
}
|
|
169
|
+
return join(root, DEFAULT_BUILD_DIR);
|
|
170
|
+
}
|
|
171
|
+
|
|
132
172
|
// ── Config file loading ───────────────────────────────────────────────────
|
|
133
173
|
|
|
134
174
|
/**
|
|
@@ -35,7 +35,7 @@ export function timberAdapterBuild(ctx: PluginContext): Plugin {
|
|
|
35
35
|
const adapter = ctx.config.adapter as TimberPlatformAdapter | undefined;
|
|
36
36
|
if (!adapter || typeof adapter.buildOutput !== 'function') return;
|
|
37
37
|
|
|
38
|
-
const buildDir =
|
|
38
|
+
const buildDir = ctx.buildDir;
|
|
39
39
|
|
|
40
40
|
// Serialize the build manifest as a JS module that sets the global.
|
|
41
41
|
// The adapter writes this as _timber-manifest-init.mjs and imports it
|
|
@@ -1,29 +1,9 @@
|
|
|
1
|
-
// @timber-js/app/segment-params — Typed route param coercion
|
|
1
|
+
// @timber-js/app/segment-params — Typed route param coercion
|
|
2
2
|
//
|
|
3
|
-
// This is the
|
|
4
|
-
//
|
|
3
|
+
// This is the import path for defineSegmentParams and related types.
|
|
4
|
+
// For search params, import from @timber-js/app/search-params instead.
|
|
5
5
|
//
|
|
6
6
|
// See design/07-routing.md §"params.ts Convention File"
|
|
7
7
|
|
|
8
|
-
// --- Segment params (route path param coercion) ---
|
|
9
8
|
export type { ParamsDefinition, InferParamField, ParamField } from './define.js';
|
|
10
9
|
export { defineSegmentParams } from './define.js';
|
|
11
|
-
|
|
12
|
-
// --- Search params (re-exported from search-params for convenience) ---
|
|
13
|
-
// This lets params.ts import both from a single path:
|
|
14
|
-
// import { defineSegmentParams, defineSearchParams } from '@timber-js/app/segment-params'
|
|
15
|
-
export { defineSearchParams } from '../search-params/define.js';
|
|
16
|
-
|
|
17
|
-
// Codec bridges moved to @timber-js/app/codec
|
|
18
|
-
// Import fromSchema / fromArraySchema from '@timber-js/app/codec' instead.
|
|
19
|
-
export { withDefault, withUrlKey } from '../search-params/wrappers.js';
|
|
20
|
-
// Codec is the canonical home for the Codec type — import from
|
|
21
|
-
// @timber-js/app/codec. Re-export removed per TIM-721.
|
|
22
|
-
export type {
|
|
23
|
-
SearchParamCodec,
|
|
24
|
-
SearchParamsDefinition,
|
|
25
|
-
SetParams,
|
|
26
|
-
SetParamsOptions,
|
|
27
|
-
QueryStatesOptions,
|
|
28
|
-
CodecMap,
|
|
29
|
-
} from '../search-params/define.js';
|
|
@@ -138,13 +138,15 @@ export interface ActionBuilder<TCtx> {
|
|
|
138
138
|
/** Declare the input schema. Validation errors are returned typed. */
|
|
139
139
|
schema<TInput>(schema: ActionSchema<TInput>): ActionBuilderWithSchema<TCtx, TInput>;
|
|
140
140
|
/** Define the action body without input validation. */
|
|
141
|
-
action<TData>(
|
|
141
|
+
action<TData>(
|
|
142
|
+
fn: (ctx: ActionContext<TCtx, undefined>) => Promise<TData>
|
|
143
|
+
): ActionFn<undefined, TData>;
|
|
142
144
|
}
|
|
143
145
|
|
|
144
146
|
/** Builder after .schema() has been called. */
|
|
145
147
|
export interface ActionBuilderWithSchema<TCtx, TInput> {
|
|
146
148
|
/** Define the action body with validated input. */
|
|
147
|
-
action<TData>(fn: (ctx: ActionContext<TCtx, TInput>) => Promise<TData>): ActionFn<TData>;
|
|
149
|
+
action<TData>(fn: (ctx: ActionContext<TCtx, TInput>) => Promise<TData>): ActionFn<TInput, TData>;
|
|
148
150
|
}
|
|
149
151
|
|
|
150
152
|
/**
|
|
@@ -159,11 +161,21 @@ export interface ActionBuilderWithSchema<TCtx, TInput> {
|
|
|
159
161
|
* discards it. This lets validated actions be passed directly to forms
|
|
160
162
|
* without casts.
|
|
161
163
|
*/
|
|
162
|
-
|
|
164
|
+
/**
|
|
165
|
+
* Map schema output keys to `string | undefined` for form-facing APIs.
|
|
166
|
+
* HTML form values are always strings, and fields can be absent.
|
|
167
|
+
* Gives autocomplete for field names without lying about value types.
|
|
168
|
+
*/
|
|
169
|
+
export type InputHint<T> =
|
|
170
|
+
T extends Record<string, unknown> ? { [K in keyof T]: string | undefined } : T;
|
|
171
|
+
|
|
172
|
+
export type ActionFn<TInput = unknown, TData = unknown> = {
|
|
163
173
|
/** <form action={fn}> compatibility — React discards the return value. */
|
|
164
174
|
(formData: FormData): void;
|
|
165
|
-
/** Direct call: action(input) */
|
|
166
|
-
(
|
|
175
|
+
/** Direct call: action(input) — optional when TInput is undefined (no-schema actions). */
|
|
176
|
+
(
|
|
177
|
+
...args: undefined extends TInput ? [input?: TInput] : [input: TInput]
|
|
178
|
+
): Promise<ActionResult<TData>>;
|
|
167
179
|
/** React useActionState: action(prevState, formData) */
|
|
168
180
|
(prevState: ActionResult<TData> | null, formData: FormData): Promise<ActionResult<TData>>;
|
|
169
181
|
};
|
|
@@ -298,7 +310,7 @@ export function createActionClient<TCtx = Record<string, never>>(
|
|
|
298
310
|
function buildAction<TInput, TData>(
|
|
299
311
|
schema: ActionSchema<TInput> | undefined,
|
|
300
312
|
fn: (ctx: ActionContext<TCtx, TInput>) => Promise<TData>
|
|
301
|
-
): ActionFn<TData> {
|
|
313
|
+
): ActionFn<TInput, TData> {
|
|
302
314
|
async function actionHandler(...args: unknown[]): Promise<ActionResult<TData>> {
|
|
303
315
|
try {
|
|
304
316
|
// Run middleware
|
|
@@ -389,18 +401,22 @@ export function createActionClient<TCtx = Record<string, never>>(
|
|
|
389
401
|
}
|
|
390
402
|
}
|
|
391
403
|
|
|
392
|
-
return actionHandler as ActionFn<TData>;
|
|
404
|
+
return actionHandler as ActionFn<TInput, TData>;
|
|
393
405
|
}
|
|
394
406
|
|
|
395
407
|
return {
|
|
396
408
|
schema<TInput>(schema: ActionSchema<TInput>) {
|
|
397
409
|
return {
|
|
398
|
-
action<TData>(
|
|
410
|
+
action<TData>(
|
|
411
|
+
fn: (ctx: ActionContext<TCtx, TInput>) => Promise<TData>
|
|
412
|
+
): ActionFn<TInput, TData> {
|
|
399
413
|
return buildAction(schema, fn);
|
|
400
414
|
},
|
|
401
415
|
};
|
|
402
416
|
},
|
|
403
|
-
action<TData>(
|
|
417
|
+
action<TData>(
|
|
418
|
+
fn: (ctx: ActionContext<TCtx, undefined>) => Promise<TData>
|
|
419
|
+
): ActionFn<undefined, TData> {
|
|
404
420
|
return buildAction(undefined, fn as (ctx: ActionContext<TCtx, unknown>) => Promise<TData>);
|
|
405
421
|
},
|
|
406
422
|
};
|
|
@@ -429,7 +445,7 @@ export function createActionClient<TCtx = Record<string, never>>(
|
|
|
429
445
|
export function validated<TInput, TData>(
|
|
430
446
|
schema: ActionSchema<TInput>,
|
|
431
447
|
handler: (input: TInput) => Promise<TData>
|
|
432
|
-
): ActionFn<TData> {
|
|
448
|
+
): ActionFn<TInput, TData> {
|
|
433
449
|
return createActionClient()
|
|
434
450
|
.schema(schema)
|
|
435
451
|
.action(async ({ input }) => handler(input));
|
package/src/server/index.ts
CHANGED
|
@@ -66,7 +66,6 @@ export { revalidatePath, revalidateTag } from './actions';
|
|
|
66
66
|
// Design doc: design/17-logging.md §"trace_id is Always Set"
|
|
67
67
|
export { getTraceId, getSpanId, withSpan, addSpanEvent } from './tracing';
|
|
68
68
|
|
|
69
|
-
// Segment params —
|
|
70
|
-
//
|
|
71
|
-
export { defineSegmentParams } from '../segment-params/define.js';
|
|
69
|
+
// Segment params types — re-exported for convenience.
|
|
70
|
+
// defineSegmentParams itself lives at @timber-js/app/segment-params.
|
|
72
71
|
export type { ParamsDefinition, InferParamField, ParamField } from '../segment-params/define.js';
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
//#region src/search-params/wrappers.ts
|
|
2
|
-
/**
|
|
3
|
-
* Wrap a nullable codec with a default value. When the inner codec returns
|
|
4
|
-
* null, the default is used instead. The output type becomes non-nullable.
|
|
5
|
-
*
|
|
6
|
-
* Works with any codec — nuqs parsers, custom codecs, fromSchema results.
|
|
7
|
-
*
|
|
8
|
-
* ```ts
|
|
9
|
-
* import { parseAsInteger } from 'nuqs'
|
|
10
|
-
* import { withDefault } from '@timber-js/app/search-params'
|
|
11
|
-
*
|
|
12
|
-
* const page = withDefault(parseAsInteger, 1)
|
|
13
|
-
* // page.parse(undefined) → 1 (not null)
|
|
14
|
-
* // page.parse('5') → 5
|
|
15
|
-
* ```
|
|
16
|
-
*/
|
|
17
|
-
function withDefault(codec, defaultValue) {
|
|
18
|
-
return {
|
|
19
|
-
parse(value) {
|
|
20
|
-
const result = codec.parse(value);
|
|
21
|
-
return result === null ? defaultValue : result;
|
|
22
|
-
},
|
|
23
|
-
serialize(value) {
|
|
24
|
-
return codec.serialize(value);
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Attach a URL key alias to a codec. The alias determines what query
|
|
30
|
-
* parameter key is used in the URL, while the TypeScript property name
|
|
31
|
-
* stays descriptive.
|
|
32
|
-
*
|
|
33
|
-
* Aliases travel with codecs through object spread composition — when
|
|
34
|
-
* you spread a bundle containing aliased codecs into defineSearchParams,
|
|
35
|
-
* the aliases come along automatically.
|
|
36
|
-
*
|
|
37
|
-
* ```ts
|
|
38
|
-
* import { parseAsString } from 'nuqs'
|
|
39
|
-
* import { withUrlKey } from '@timber-js/app/search-params'
|
|
40
|
-
*
|
|
41
|
-
* export const searchable = {
|
|
42
|
-
* q: withUrlKey(parseAsString, 'search'),
|
|
43
|
-
* // ?search=shoes → { q: 'shoes' }
|
|
44
|
-
* }
|
|
45
|
-
* ```
|
|
46
|
-
*
|
|
47
|
-
* Composes with withDefault:
|
|
48
|
-
* ```ts
|
|
49
|
-
* import { parseAsInteger } from 'nuqs'
|
|
50
|
-
* withUrlKey(withDefault(parseAsInteger, 1), 'p')
|
|
51
|
-
* ```
|
|
52
|
-
*/
|
|
53
|
-
function withUrlKey(codec, urlKey) {
|
|
54
|
-
return {
|
|
55
|
-
parse: codec.parse.bind(codec),
|
|
56
|
-
serialize: codec.serialize.bind(codec),
|
|
57
|
-
urlKey
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
//#endregion
|
|
61
|
-
export { withUrlKey as n, withDefault as t };
|
|
62
|
-
|
|
63
|
-
//# sourceMappingURL=wrappers-_DTmImGt.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wrappers-_DTmImGt.js","names":[],"sources":["../../src/search-params/wrappers.ts"],"sourcesContent":["/**\n * Codec wrappers — withDefault and withUrlKey.\n *\n * These are timber-specific utilities that work with any SearchParamCodec.\n * For actual codecs (string, integer, boolean, etc.), use nuqs parsers\n * or Standard Schema objects (Zod, Valibot, ArkType) with auto-detection.\n *\n * Design doc: design/23-search-params.md\n */\n\nimport type { SearchParamCodec, SearchParamCodecWithUrlKey } from './define.js';\n\n// ---------------------------------------------------------------------------\n// withDefault\n// ---------------------------------------------------------------------------\n\n/**\n * Wrap a nullable codec with a default value. When the inner codec returns\n * null, the default is used instead. The output type becomes non-nullable.\n *\n * Works with any codec — nuqs parsers, custom codecs, fromSchema results.\n *\n * ```ts\n * import { parseAsInteger } from 'nuqs'\n * import { withDefault } from '@timber-js/app/search-params'\n *\n * const page = withDefault(parseAsInteger, 1)\n * // page.parse(undefined) → 1 (not null)\n * // page.parse('5') → 5\n * ```\n */\nexport function withDefault<T>(\n codec: SearchParamCodec<T | null>,\n defaultValue: T\n): SearchParamCodec<T> {\n return {\n parse(value: string | string[] | undefined): T {\n const result = codec.parse(value);\n return result === null ? defaultValue : result;\n },\n serialize(value: T): string | null {\n return codec.serialize(value);\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// withUrlKey\n// ---------------------------------------------------------------------------\n\n/**\n * Attach a URL key alias to a codec. The alias determines what query\n * parameter key is used in the URL, while the TypeScript property name\n * stays descriptive.\n *\n * Aliases travel with codecs through object spread composition — when\n * you spread a bundle containing aliased codecs into defineSearchParams,\n * the aliases come along automatically.\n *\n * ```ts\n * import { parseAsString } from 'nuqs'\n * import { withUrlKey } from '@timber-js/app/search-params'\n *\n * export const searchable = {\n * q: withUrlKey(parseAsString, 'search'),\n * // ?search=shoes → { q: 'shoes' }\n * }\n * ```\n *\n * Composes with withDefault:\n * ```ts\n * import { parseAsInteger } from 'nuqs'\n * withUrlKey(withDefault(parseAsInteger, 1), 'p')\n * ```\n */\nexport function withUrlKey<T>(\n codec: SearchParamCodec<T>,\n urlKey: string\n): SearchParamCodecWithUrlKey<T> {\n return {\n parse: codec.parse.bind(codec),\n serialize: codec.serialize.bind(codec),\n urlKey,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA+BA,SAAgB,YACd,OACA,cACqB;AACrB,QAAO;EACL,MAAM,OAAyC;GAC7C,MAAM,SAAS,MAAM,MAAM,MAAM;AACjC,UAAO,WAAW,OAAO,eAAe;;EAE1C,UAAU,OAAyB;AACjC,UAAO,MAAM,UAAU,MAAM;;EAEhC;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCH,SAAgB,WACd,OACA,QAC+B;AAC/B,QAAO;EACL,OAAO,MAAM,MAAM,KAAK,MAAM;EAC9B,WAAW,MAAM,UAAU,KAAK,MAAM;EACtC;EACD"}
|