@kuratchi/js 0.0.9 → 0.0.10

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.
@@ -4,7 +4,7 @@
4
4
  * Extracts the top-level compile-time <script> block (before the HTML document).
5
5
  * A top-level block containing reactive `$:` labels is preserved in template output
6
6
  * as client script.
7
- * Everything else is the template — full HTML with native JS flow control.
7
+ * Everything else is the template full HTML with native JS flow control.
8
8
  * <style> inside the HTML is NOT extracted; it's part of the template.
9
9
  */
10
10
  export interface ParsedFile {
@@ -12,7 +12,7 @@ export interface ParsedFile {
12
12
  script: string | null;
13
13
  /** Explicit server-side load function exported from the route script */
14
14
  loadFunction: string | null;
15
- /** Template — the full HTML document with inline JS flow control */
15
+ /** Template the full HTML document with inline JS flow control */
16
16
  template: string;
17
17
  /** All imports from the script block */
18
18
  serverImports: string[];
@@ -22,7 +22,7 @@ export interface ParsedFile {
22
22
  actionFunctions: string[];
23
23
  /** Top-level variable names declared in the script (const/let/var) */
24
24
  dataVars: string[];
25
- /** Component imports: import Name from '$lib/file.html' → { Name: 'file' } */
25
+ /** Component imports: import Name from '$lib/file.html' { Name: 'file' } */
26
26
  componentImports: Record<string, string>;
27
27
  /** Poll functions referenced via data-poll={fn(args)} in the template */
28
28
  pollFunctions: string[];
@@ -47,6 +47,7 @@ interface ParseFileOptions {
47
47
  kind?: 'route' | 'layout' | 'component';
48
48
  filePath?: string;
49
49
  }
50
+ export declare function stripTopLevelImports(source: string): string;
50
51
  /**
51
52
  * Parse a .html route file.
52
53
  *
@@ -1,12 +1,31 @@
1
- /**
2
- * HTML file parser.
3
- *
4
- * Extracts the top-level compile-time <script> block (before the HTML document).
5
- * A top-level block containing reactive `$:` labels is preserved in template output
6
- * as client script.
7
- * Everything else is the template — full HTML with native JS flow control.
8
- * <style> inside the HTML is NOT extracted; it's part of the template.
9
- */
1
+ import ts from 'typescript';
2
+ function getTopLevelImportStatements(source) {
3
+ const sourceFile = ts.createSourceFile('kuratchi-script.ts', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
4
+ const imports = [];
5
+ for (const statement of sourceFile.statements) {
6
+ if (!ts.isImportDeclaration(statement))
7
+ continue;
8
+ imports.push({
9
+ text: source.slice(statement.getStart(sourceFile), statement.getEnd()),
10
+ start: statement.getStart(sourceFile),
11
+ end: statement.getEnd(),
12
+ });
13
+ }
14
+ return imports;
15
+ }
16
+ export function stripTopLevelImports(source) {
17
+ const imports = getTopLevelImportStatements(source);
18
+ if (imports.length === 0)
19
+ return source.trim();
20
+ let cursor = 0;
21
+ let output = '';
22
+ for (const statement of imports) {
23
+ output += source.slice(cursor, statement.start);
24
+ cursor = statement.end;
25
+ }
26
+ output += source.slice(cursor);
27
+ return output.trim();
28
+ }
10
29
  function hasReactiveLabel(scriptBody) {
11
30
  return /\$\s*:/.test(scriptBody);
12
31
  }
@@ -670,11 +689,8 @@ export function parseFile(source, options = {}) {
670
689
  const workerEnvAliases = [];
671
690
  const devAliases = [];
672
691
  if (script) {
673
- // Support both single-line and multiline static imports.
674
- const importRegex = /^\s*import[\s\S]*?from\s+['"][^'"]+['"]\s*;?/gm;
675
- let m;
676
- while ((m = importRegex.exec(script)) !== null) {
677
- const line = m[0].trim();
692
+ for (const statement of getTopLevelImportStatements(script)) {
693
+ const line = statement.text.trim();
678
694
  // Check for component imports: import Name from '$lib/file.html' or '@kuratchi/ui/file.html'
679
695
  const libMatch = line.match(/import\s+([A-Za-z_$][\w$]*)\s+from\s+['"]\$lib\/([^'"]+\.html)['"]/s);
680
696
  const pkgMatch = !libMatch ? line.match(/import\s+([A-Za-z_$][\w$]*)\s+from\s+['"](@[^/'"]+\/[^/'"]+)\/([^'"]+\.html)['"]/s) : null;
@@ -707,10 +723,8 @@ export function parseFile(source, options = {}) {
707
723
  }
708
724
  }
709
725
  if (clientScript) {
710
- const importRegex = /^\s*import[\s\S]*?from\s+['"][^'"]+['"]\s*;?/gm;
711
- let m;
712
- while ((m = importRegex.exec(clientScript)) !== null) {
713
- const line = m[0].trim();
726
+ for (const statement of getTopLevelImportStatements(clientScript)) {
727
+ const line = statement.text.trim();
714
728
  clientImports.push(line);
715
729
  if (extractKuratchiEnvironmentDevAliases(line).length > 0) {
716
730
  throw new Error(`[kuratchi compiler] ${options.filePath || kind}\nClient <script> blocks cannot import from @kuratchi/js/environment.\nUse route server script code and pass values into the template explicitly.`);
@@ -729,8 +743,7 @@ export function parseFile(source, options = {}) {
729
743
  let scriptBody = '';
730
744
  let loadFunction = null;
731
745
  if (script) {
732
- // Remove import lines to get the script body
733
- const rawScriptBody = script.replace(/^\s*import[\s\S]*?from\s+['"][^'"]+['"]\s*;?/gm, '').trim();
746
+ const rawScriptBody = stripTopLevelImports(script);
734
747
  const explicitLoad = extractExplicitLoad(rawScriptBody);
735
748
  scriptBody = explicitLoad.remainingScript;
736
749
  loadFunction = explicitLoad.loadFunction;
@@ -773,7 +786,7 @@ export function parseFile(source, options = {}) {
773
786
  }
774
787
  }
775
788
  // Also collect onX={fnName(...)} candidates (e.g. onclick, onClick, onChange)
776
- // — the compiler will filter these against actual imports to determine server actions.
789
+ // the compiler will filter these against actual imports to determine server actions.
777
790
  const eventActionRegex = /on[A-Za-z]+\s*=\{(\w+)\s*\(/g;
778
791
  let em;
779
792
  while ((em = eventActionRegex.exec(templateWithoutComments)) !== null) {
@@ -49,6 +49,8 @@ export function compileTemplate(template, componentNames, actionNames, rpcNameMa
49
49
  let inStyle = false;
50
50
  let inScript = false;
51
51
  let scriptBuffer = [];
52
+ let inHtmlTag = false;
53
+ let htmlAttrQuote = null;
52
54
  for (let i = 0; i < lines.length; i++) {
53
55
  const line = lines[i];
54
56
  const trimmed = line.trim();
@@ -87,6 +89,16 @@ export function compileTemplate(template, componentNames, actionNames, rpcNameMa
87
89
  }
88
90
  continue;
89
91
  }
92
+ const startedInsideQuotedAttr = !!htmlAttrQuote;
93
+ const nextHtmlState = advanceHtmlTagState(line, inHtmlTag, htmlAttrQuote);
94
+ if (startedInsideQuotedAttr) {
95
+ out.push(`__html += \`${escapeLiteral(line)}\n\`;`);
96
+ inHtmlTag = nextHtmlState.inTag;
97
+ htmlAttrQuote = nextHtmlState.quote;
98
+ continue;
99
+ }
100
+ inHtmlTag = nextHtmlState.inTag;
101
+ htmlAttrQuote = nextHtmlState.quote;
90
102
  // Skip empty lines
91
103
  if (!trimmed) {
92
104
  out.push('__html += "\\n";');
@@ -167,6 +179,36 @@ export function compileTemplate(template, componentNames, actionNames, rpcNameMa
167
179
  }
168
180
  return out.join('\n');
169
181
  }
182
+ function advanceHtmlTagState(src, startInTag, startQuote) {
183
+ let inTag = startInTag;
184
+ let quote = startQuote;
185
+ for (let i = 0; i < src.length; i++) {
186
+ const ch = src[i];
187
+ if (quote) {
188
+ if (ch === '\\') {
189
+ i++;
190
+ continue;
191
+ }
192
+ if (ch === quote)
193
+ quote = null;
194
+ continue;
195
+ }
196
+ if (!inTag) {
197
+ if (ch === '<') {
198
+ inTag = true;
199
+ }
200
+ continue;
201
+ }
202
+ if (ch === '"' || ch === "'") {
203
+ quote = ch;
204
+ continue;
205
+ }
206
+ if (ch === '>') {
207
+ inTag = false;
208
+ }
209
+ }
210
+ return { inTag, quote };
211
+ }
170
212
  function transformClientScriptBlock(block) {
171
213
  const match = block.match(/^([\s\S]*?<script\b[^>]*>)([\s\S]*?)(<\/script>\s*)$/i);
172
214
  if (!match)
@@ -566,7 +608,7 @@ function compileHtmlLine(line, actionNames, rpcNameMap) {
566
608
  let pos = 0;
567
609
  let hasExpr = false;
568
610
  while (pos < line.length) {
569
- const braceIdx = line.indexOf('{', pos);
611
+ const braceIdx = findNextTemplateBrace(line, pos);
570
612
  if (braceIdx === -1) {
571
613
  // No more braces — rest is literal
572
614
  result += escapeLiteral(line.slice(pos));
@@ -777,13 +819,36 @@ function escapeLiteral(text) {
777
819
  .replace(/`/g, '\\`')
778
820
  .replace(/\$\{/g, '\\${');
779
821
  }
822
+ function findNextTemplateBrace(src, startPos) {
823
+ return src.indexOf('{', startPos);
824
+ }
780
825
  /** Find the matching closing `}` for an opening `{`, handling nesting. */
781
826
  function findClosingBrace(src, openPos) {
782
827
  let depth = 0;
828
+ let quote = null;
829
+ let escaped = false;
783
830
  for (let i = openPos; i < src.length; i++) {
784
- if (src[i] === '{')
831
+ const ch = src[i];
832
+ if (quote) {
833
+ if (escaped) {
834
+ escaped = false;
835
+ continue;
836
+ }
837
+ if (ch === '\\') {
838
+ escaped = true;
839
+ continue;
840
+ }
841
+ if (ch === quote)
842
+ quote = null;
843
+ continue;
844
+ }
845
+ if (ch === '"' || ch === "'" || ch === '`') {
846
+ quote = ch;
847
+ continue;
848
+ }
849
+ if (ch === '{')
785
850
  depth++;
786
- if (src[i] === '}') {
851
+ if (ch === '}') {
787
852
  depth--;
788
853
  if (depth === 0)
789
854
  return i;
@@ -816,13 +881,13 @@ export function generateRenderFunction(template) {
816
881
  const __esc = (v) => {
817
882
  if (v == null) return '';
818
883
  return String(v)
819
- .replace(/&/g, '&amp;')
820
- .replace(/</g, '&lt;')
821
- .replace(/>/g, '&gt;')
822
- .replace(/"/g, '&quot;')
823
- .replace(/'/g, '&#39;');
824
- };
825
- ${body}
884
+ .replace(/&/g, '&amp;')
885
+ .replace(/</g, '&lt;')
886
+ .replace(/>/g, '&gt;')
887
+ .replace(/"/g, '&quot;')
888
+ .replace(/'/g, '&#39;');
889
+ };
890
+ ${body}
826
891
  }`;
827
892
  }
828
893
  import { transpileTypeScript } from './transpile.js';
package/dist/create.js CHANGED
@@ -633,7 +633,7 @@ ${types}
633
633
  function genItemsCrud() {
634
634
  return `import { env } from 'cloudflare:workers';
635
635
  import { kuratchiORM } from '@kuratchi/orm';
636
- import { getLocals } from '${FRAMEWORK_PACKAGE_NAME}';
636
+ import { redirect } from '${FRAMEWORK_PACKAGE_NAME}';
637
637
  import type { Item } from './schemas/app';
638
638
 
639
639
  const db = kuratchiORM(() => (env as any).DB);
@@ -718,7 +718,7 @@ import {
718
718
  parseSessionCookie,
719
719
  } from '@kuratchi/auth';
720
720
  import { getAuth } from '@kuratchi/auth';
721
- import { getLocals } from '${FRAMEWORK_PACKAGE_NAME}';
721
+ import { redirect } from '${FRAMEWORK_PACKAGE_NAME}';
722
722
  import type { User } from '../schemas/app';
723
723
 
724
724
  const db = kuratchiORM(() => (env as any).DB);
@@ -759,7 +759,7 @@ export async function signUp(formData: FormData): Promise<void> {
759
759
  }
760
760
 
761
761
  // Redirect to login after successful signup
762
- getLocals().__redirectTo = '/auth/login';
762
+ redirect('/auth/login');
763
763
  }
764
764
 
765
765
  // ── Sign In ─────────────────────────────────────────────────
@@ -823,7 +823,7 @@ export async function signIn(formData: FormData): Promise<void> {
823
823
  locals.__setCookieHeaders.push(setCookieHeader);
824
824
 
825
825
  // Redirect to admin after successful login
826
- locals.__redirectTo = '/admin';
826
+ redirect('/admin');
827
827
  }
828
828
 
829
829
  // ── Sign Out ────────────────────────────────────────────────
@@ -847,7 +847,7 @@ export async function signOut(formData: FormData): Promise<void> {
847
847
  locals.__setCookieHeaders.push(clearHeader);
848
848
 
849
849
  // Redirect to login after sign out
850
- locals.__redirectTo = '/auth/login';
850
+ redirect('/auth/login');
851
851
  }
852
852
 
853
853
  // ── Get Current User ────────────────────────────────────────
package/dist/index.d.ts CHANGED
@@ -6,10 +6,11 @@
6
6
  export { createApp } from './runtime/app.js';
7
7
  export { defineConfig } from './runtime/config.js';
8
8
  export { defineRuntime } from './runtime/runtime.js';
9
- export { getCtx, getEnv, getRequest, getLocals, getParams, getParam, redirect, goto, setBreadcrumbs, getBreadcrumbs, breadcrumbsHome, breadcrumbsPrev, breadcrumbsNext, breadcrumbsCurrent, buildDefaultBreadcrumbs, } from './runtime/context.js';
9
+ export { getCtx, getEnv, getRequest, getLocals, getParams, getParam, RedirectError, redirect, goto, setBreadcrumbs, getBreadcrumbs, breadcrumbsHome, breadcrumbsPrev, breadcrumbsNext, breadcrumbsCurrent, buildDefaultBreadcrumbs, } from './runtime/context.js';
10
10
  export { kuratchiDO, doRpc, getDb } from './runtime/do.js';
11
11
  export { ActionError } from './runtime/action.js';
12
12
  export { PageError } from './runtime/page-error.js';
13
13
  export { extractSubdomainSlug, extractSlugFromPrefix, matchContainerViewPath, rewriteProxyLocationHeader, buildContainerRequest, createContainerEnvVars, startContainer, proxyToContainer, handleContainerRouting, forwardJsonPostToContainerDO, matchSiteViewPath, buildSiteContainerRequest, createWpContainerEnvVars, startSiteContainer, proxyToSiteContainer, } from './runtime/containers.js';
14
14
  export type { AppConfig, kuratchiConfig, DatabaseConfig, AuthConfig, RouteContext, RouteModule, RuntimeContext, RuntimeDefinition, RuntimeStep, RuntimeNext, RuntimeErrorResult, } from './runtime/types.js';
15
15
  export type { RpcOf } from './runtime/do.js';
16
+ export { url, pathname, searchParams, headers, method, params, slug } from './runtime/request.js';
package/dist/index.js CHANGED
@@ -7,10 +7,11 @@
7
7
  export { createApp } from './runtime/app.js';
8
8
  export { defineConfig } from './runtime/config.js';
9
9
  export { defineRuntime } from './runtime/runtime.js';
10
- export { getCtx, getEnv, getRequest, getLocals, getParams, getParam, redirect, goto, setBreadcrumbs, getBreadcrumbs, breadcrumbsHome, breadcrumbsPrev, breadcrumbsNext, breadcrumbsCurrent, buildDefaultBreadcrumbs, } from './runtime/context.js';
10
+ export { getCtx, getEnv, getRequest, getLocals, getParams, getParam, RedirectError, redirect, goto, setBreadcrumbs, getBreadcrumbs, breadcrumbsHome, breadcrumbsPrev, breadcrumbsNext, breadcrumbsCurrent, buildDefaultBreadcrumbs, } from './runtime/context.js';
11
11
  export { kuratchiDO, doRpc, getDb } from './runtime/do.js';
12
12
  export { ActionError } from './runtime/action.js';
13
13
  export { PageError } from './runtime/page-error.js';
14
14
  export { extractSubdomainSlug, extractSlugFromPrefix, matchContainerViewPath, rewriteProxyLocationHeader, buildContainerRequest, createContainerEnvVars, startContainer, proxyToContainer, handleContainerRouting, forwardJsonPostToContainerDO,
15
15
  // Compatibility aliases
16
16
  matchSiteViewPath, buildSiteContainerRequest, createWpContainerEnvVars, startSiteContainer, proxyToSiteContainer, } from './runtime/containers.js';
17
+ export { url, pathname, searchParams, headers, method, params, slug } from './runtime/request.js';
@@ -12,6 +12,12 @@ export interface BreadcrumbItem {
12
12
  href?: string;
13
13
  current?: boolean;
14
14
  }
15
+ export declare class RedirectError extends Error {
16
+ readonly isRedirectError = true;
17
+ readonly location: string;
18
+ readonly status: number;
19
+ constructor(path: string, status?: number);
20
+ }
15
21
  /** Called by the framework at the start of each request */
16
22
  export declare function __setRequestContext(ctx: any, request: Request, env?: Record<string, any>): void;
17
23
  /** Get the execution context (Worker: ExecutionContext, DO: DurableObjectState) */
@@ -28,11 +34,11 @@ export declare function getParams<T = Record<string, string>>(): T;
28
34
  export declare function getParam(name: string): string | undefined;
29
35
  /**
30
36
  * Server-side redirect helper for actions/load logic.
31
- * Sets the post-action redirect target consumed by the framework's PRG flow.
37
+ * Throws a redirect signal consumed by the framework's PRG flow.
32
38
  */
33
- export declare function redirect(path: string, status?: number): void;
39
+ export declare function redirect(path: string, status?: number): never;
34
40
  /** Backward-compatible alias for redirect() */
35
- export declare function goto(path: string, status?: number): void;
41
+ export declare function goto(path: string, status?: number): never;
36
42
  export declare function setBreadcrumbs(items: BreadcrumbItem[]): void;
37
43
  export declare function getBreadcrumbs(): BreadcrumbItem[];
38
44
  export declare function breadcrumbsHome(label?: string, href?: string): BreadcrumbItem;
@@ -8,16 +8,29 @@
8
8
  * variables are safe and require no Node.js compat flags.
9
9
  */
10
10
  import { __getDoSelf } from './do.js';
11
+ import { __setRequestParams, __setRequestState } from './request.js';
11
12
  let __ctx = null;
12
13
  let __request = null;
13
14
  let __env = null;
14
15
  let __locals = {};
16
+ export class RedirectError extends Error {
17
+ isRedirectError = true;
18
+ location;
19
+ status;
20
+ constructor(path, status = 303) {
21
+ super(`Redirect to ${path}`);
22
+ this.name = 'RedirectError';
23
+ this.location = path;
24
+ this.status = status;
25
+ }
26
+ }
15
27
  /** Called by the framework at the start of each request */
16
28
  export function __setRequestContext(ctx, request, env) {
17
29
  __ctx = ctx;
18
30
  __request = request;
19
31
  __env = env ?? null;
20
32
  __locals = {};
33
+ __setRequestState(request);
21
34
  // Expose context on globalThis for @kuratchi/auth and other packages
22
35
  // Workers are single-threaded per request — this is safe
23
36
  globalThis.__kuratchi_context__ = {
@@ -63,11 +76,12 @@ export function getParam(name) {
63
76
  }
64
77
  /**
65
78
  * Server-side redirect helper for actions/load logic.
66
- * Sets the post-action redirect target consumed by the framework's PRG flow.
79
+ * Throws a redirect signal consumed by the framework's PRG flow.
67
80
  */
68
81
  export function redirect(path, status = 303) {
69
82
  __locals.__redirectTo = path;
70
83
  __locals.__redirectStatus = status;
84
+ throw new RedirectError(path, status);
71
85
  }
72
86
  /** Backward-compatible alias for redirect() */
73
87
  export function goto(path, status = 303) {
@@ -120,6 +134,8 @@ export function buildDefaultBreadcrumbs(pathname, _params = {}) {
120
134
  /** Set a value on request-scoped locals (used by framework internals) */
121
135
  export function __setLocal(key, value) {
122
136
  __locals[key] = value;
137
+ if (key === 'params')
138
+ __setRequestParams(value);
123
139
  }
124
140
  /** Get the full locals object reference (used by framework internals) */
125
141
  export function __getLocals() {
@@ -2,8 +2,9 @@ export { createApp } from './app.js';
2
2
  export { defineConfig } from './config.js';
3
3
  export { defineRuntime } from './runtime.js';
4
4
  export { Router, filePathToPattern } from './router.js';
5
- export { getCtx, getRequest, getLocals, getParams, getParam, redirect, goto, setBreadcrumbs, getBreadcrumbs, breadcrumbsHome, breadcrumbsPrev, breadcrumbsNext, breadcrumbsCurrent, buildDefaultBreadcrumbs, } from './context.js';
5
+ export { getCtx, getRequest, getLocals, getParams, getParam, RedirectError, redirect, goto, setBreadcrumbs, getBreadcrumbs, breadcrumbsHome, breadcrumbsPrev, breadcrumbsNext, breadcrumbsCurrent, buildDefaultBreadcrumbs, } from './context.js';
6
6
  export { kuratchiDO, doRpc } from './do.js';
7
7
  export { extractSubdomainSlug, extractSlugFromPrefix, matchContainerViewPath, rewriteProxyLocationHeader, buildContainerRequest, createContainerEnvVars, startContainer, proxyToContainer, handleContainerRouting, forwardJsonPostToContainerDO, matchSiteViewPath, buildSiteContainerRequest, createWpContainerEnvVars, startSiteContainer, proxyToSiteContainer, } from './containers.js';
8
8
  export type { AppConfig, Env, AuthConfig, RouteContext, RouteModule, ApiRouteModule, HttpMethod, LayoutModule, RuntimeContext, RuntimeDefinition, RuntimeStep, RuntimeNext, RuntimeErrorResult, } from './types.js';
9
9
  export type { RpcOf } from './do.js';
10
+ export { url, pathname, searchParams, headers, method, params, slug } from './request.js';
@@ -2,8 +2,9 @@ export { createApp } from './app.js';
2
2
  export { defineConfig } from './config.js';
3
3
  export { defineRuntime } from './runtime.js';
4
4
  export { Router, filePathToPattern } from './router.js';
5
- export { getCtx, getRequest, getLocals, getParams, getParam, redirect, goto, setBreadcrumbs, getBreadcrumbs, breadcrumbsHome, breadcrumbsPrev, breadcrumbsNext, breadcrumbsCurrent, buildDefaultBreadcrumbs, } from './context.js';
5
+ export { getCtx, getRequest, getLocals, getParams, getParam, RedirectError, redirect, goto, setBreadcrumbs, getBreadcrumbs, breadcrumbsHome, breadcrumbsPrev, breadcrumbsNext, breadcrumbsCurrent, buildDefaultBreadcrumbs, } from './context.js';
6
6
  export { kuratchiDO, doRpc } from './do.js';
7
7
  export { extractSubdomainSlug, extractSlugFromPrefix, matchContainerViewPath, rewriteProxyLocationHeader, buildContainerRequest, createContainerEnvVars, startContainer, proxyToContainer, handleContainerRouting, forwardJsonPostToContainerDO,
8
8
  // Compatibility aliases
9
9
  matchSiteViewPath, buildSiteContainerRequest, createWpContainerEnvVars, startSiteContainer, proxyToSiteContainer, } from './containers.js';
10
+ export { url, pathname, searchParams, headers, method, params, slug } from './request.js';
@@ -0,0 +1,9 @@
1
+ export declare let url: URL;
2
+ export declare let pathname: string;
3
+ export declare let searchParams: URLSearchParams;
4
+ export declare let headers: Headers;
5
+ export declare let method: string;
6
+ export declare let params: Record<string, string>;
7
+ export declare let slug: string | undefined;
8
+ export declare function __setRequestState(request: Request): void;
9
+ export declare function __setRequestParams(nextParams: Record<string, string> | null | undefined): void;
@@ -0,0 +1,23 @@
1
+ export let url = new URL('http://localhost/');
2
+ export let pathname = '/';
3
+ export let searchParams = url.searchParams;
4
+ export let headers = new Headers();
5
+ export let method = 'GET';
6
+ export let params = {};
7
+ export let slug = undefined;
8
+ function __syncDerivedState() {
9
+ pathname = url.pathname;
10
+ searchParams = url.searchParams;
11
+ slug = params.slug;
12
+ }
13
+ export function __setRequestState(request) {
14
+ url = new URL(request.url);
15
+ headers = request.headers;
16
+ method = request.method;
17
+ params = {};
18
+ __syncDerivedState();
19
+ }
20
+ export function __setRequestParams(nextParams) {
21
+ params = nextParams ?? {};
22
+ __syncDerivedState();
23
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kuratchi/js",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
4
4
  "description": "A thin, Cloudflare Workers-native web framework with Svelte-inspired syntax",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -28,6 +28,10 @@
28
28
  "types": "./dist/runtime/context.d.ts",
29
29
  "import": "./dist/runtime/context.js"
30
30
  },
31
+ "./request": {
32
+ "types": "./dist/runtime/request.d.ts",
33
+ "import": "./dist/runtime/request.js"
34
+ },
31
35
  "./runtime/do.js": {
32
36
  "types": "./dist/runtime/do.d.ts",
33
37
  "import": "./dist/runtime/do.js"