tina4js 1.0.13 → 1.0.15

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.
Files changed (47) hide show
  1. package/bin/tina4.js +14 -14
  2. package/dist/api.cjs.js +1 -1
  3. package/dist/api.es.js +116 -56
  4. package/package.json +3 -3
  5. package/readme.md +4 -4
  6. package/dist/api/fetch.d.ts +0 -105
  7. package/dist/api/fetch.d.ts.map +0 -1
  8. package/dist/api/index.d.ts +0 -6
  9. package/dist/api/index.d.ts.map +0 -1
  10. package/dist/core/component.d.ts +0 -59
  11. package/dist/core/component.d.ts.map +0 -1
  12. package/dist/core/html.d.ts +0 -37
  13. package/dist/core/html.d.ts.map +0 -1
  14. package/dist/core/index.d.ts +0 -9
  15. package/dist/core/index.d.ts.map +0 -1
  16. package/dist/core/signal.d.ts +0 -101
  17. package/dist/core/signal.d.ts.map +0 -1
  18. package/dist/debug/index.d.ts +0 -17
  19. package/dist/debug/index.d.ts.map +0 -1
  20. package/dist/debug/overlay.d.ts +0 -25
  21. package/dist/debug/overlay.d.ts.map +0 -1
  22. package/dist/debug/panels/api.d.ts +0 -5
  23. package/dist/debug/panels/api.d.ts.map +0 -1
  24. package/dist/debug/panels/components.d.ts +0 -5
  25. package/dist/debug/panels/components.d.ts.map +0 -1
  26. package/dist/debug/panels/routes.d.ts +0 -5
  27. package/dist/debug/panels/routes.d.ts.map +0 -1
  28. package/dist/debug/panels/signals.d.ts +0 -5
  29. package/dist/debug/panels/signals.d.ts.map +0 -1
  30. package/dist/debug/styles.d.ts +0 -5
  31. package/dist/debug/styles.d.ts.map +0 -1
  32. package/dist/debug/trackers.d.ts +0 -89
  33. package/dist/debug/trackers.d.ts.map +0 -1
  34. package/dist/index.d.ts +0 -19
  35. package/dist/index.d.ts.map +0 -1
  36. package/dist/pwa/index.d.ts +0 -6
  37. package/dist/pwa/index.d.ts.map +0 -1
  38. package/dist/pwa/pwa.d.ts +0 -24
  39. package/dist/pwa/pwa.d.ts.map +0 -1
  40. package/dist/router/index.d.ts +0 -6
  41. package/dist/router/index.d.ts.map +0 -1
  42. package/dist/router/router.d.ts +0 -72
  43. package/dist/router/router.d.ts.map +0 -1
  44. package/dist/ws/index.d.ts +0 -6
  45. package/dist/ws/index.d.ts.map +0 -1
  46. package/dist/ws/ws.d.ts +0 -62
  47. package/dist/ws/ws.d.ts.map +0 -1
package/bin/tina4.js CHANGED
@@ -4,8 +4,8 @@
4
4
  * Tina4 CLI — Project scaffolding and build tooling.
5
5
  *
6
6
  * Usage:
7
- * npx tina4 create <name> Scaffold a new project
8
- * npx tina4 create <name> --pwa Include PWA support
7
+ * npx tina4js create <name> Scaffold a new project
8
+ * npx tina4js create <name> --pwa Include PWA support
9
9
  * npx tina4 build Production build
10
10
  * npx tina4 build --target php Build for tina4-php embedding
11
11
  * npx tina4 build --target python Build for tina4-python embedding
@@ -201,7 +201,7 @@ route('/', homePage);
201
201
  route('/about', () => html\`
202
202
  <div class="page">
203
203
  <h1>About</h1>
204
- <p>Built with <a href="https://github.com/tina4stack/tina4-js">tina4-js</a> — a sub-3KB reactive framework.</p>
204
+ <p>Built with <a href="https://github.com/tina4stack/tina4-js">tina4-js</a> — a sub-3KB core, reactive framework.</p>
205
205
  <a href="/">Back home</a>
206
206
  </div>
207
207
  \`);
@@ -443,21 +443,21 @@ async def spa_catchall(path, request, response):
443
443
 
444
444
  function printHelp() {
445
445
  console.log(`
446
- ${c.bold('tina4')} — Sub-3KB reactive framework
446
+ ${c.bold('tina4js')} — Sub-3KB core, reactive framework
447
447
 
448
448
  ${c.bold('Usage:')}
449
- tina4 create <name> Create a new project
450
- tina4 create <name> --pwa Create with PWA support
451
- tina4 create <name> --css Create with tina4-css framework
452
- tina4 create <name> --pwa --css Create with both
453
- tina4 dev Start dev server
454
- tina4 build Production build → dist/
455
- tina4 build --target php Build for tina4-php
456
- tina4 build --target python Build for tina4-python
449
+ tina4js create <name> Create a new project
450
+ tina4js create <name> --pwa Create with PWA support
451
+ tina4js create <name> --css Create with tina4-css framework
452
+ tina4js create <name> --pwa --css Create with both
453
+ tina4js dev Start dev server
454
+ tina4js build Production build → dist/
455
+ tina4js build --target php Build for tina4-php
456
+ tina4js build --target python Build for tina4-python
457
457
 
458
458
  ${c.bold('Examples:')}
459
- ${c.dim('$')} npx tina4 create my-app
460
- ${c.dim('$')} npx tina4 create my-app --css
459
+ ${c.dim('$')} npx tina4js create my-app
460
+ ${c.dim('$')} npx tina4js create my-app --css
461
461
  ${c.dim('$')} cd my-app && npm install && npm run dev
462
462
  `);
463
463
  }
package/dist/api.cjs.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s={baseUrl:"",auth:!1,tokenKey:"tina4_token",headers:{}},d=[],h=[];let j=0;function T(){try{return localStorage.getItem(s.tokenKey)}catch{return null}}function I(e){try{localStorage.setItem(s.tokenKey,e)}catch{}}async function i(e,t,n,c){let o={method:e,headers:{"Content-Type":"application/json",...s.headers}};if(s.auth){const r=T();r&&(o.headers.Authorization=`Bearer ${r}`)}if(n!==void 0&&e!=="GET"){let r=typeof n=="object"&&n!==null?{...n}:n;if(s.auth&&typeof r=="object"&&r!==null){const a=T();a&&(r.formToken=a)}o.body=JSON.stringify(r)}if(c!=null&&c.headers&&Object.assign(o.headers,c.headers),c!=null&&c.params){const r=Object.entries(c.params).map(([a,y])=>`${encodeURIComponent(a)}=${encodeURIComponent(String(y))}`).join("&");t+=(t.includes("?")?"&":"?")+r}const g=s.baseUrl+t;o._url=g,o._requestId=++j;for(const r of d){const a=r(o);a&&(o=a)}const u=await fetch(g,o),k=u.headers.get("FreshToken");k&&I(k);const p=u.headers.get("Content-Type")??"";let f;p.includes("json")?f=await u.json():f=await u.text();let l={status:u.status,data:f,ok:u.ok,headers:u.headers,_requestId:o._requestId};for(const r of h){const a=r(l);a&&(l=a)}if(!u.ok)throw l;return l.data}const q={configure(e){Object.assign(s,e)},get(e,t){return i("GET",e,void 0,t)},post(e,t,n){return i("POST",e,t,n)},put(e,t,n){return i("PUT",e,t,n)},patch(e,t,n){return i("PATCH",e,t,n)},delete(e,t){return i("DELETE",e,void 0,t)},intercept(e,t){e==="request"?d.push(t):h.push(t)},_reset(){s.baseUrl="",s.auth=!1,s.tokenKey="tina4_token",s.headers={},d.length=0,h.length=0}};exports.api=q;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a={baseUrl:"",auth:!1,tokenKey:"tina4_token",headers:{}},k=[],T=[];let j=0;function y(){try{return localStorage.getItem(a.tokenKey)}catch{return null}}function I(e){try{localStorage.setItem(a.tokenKey,e)}catch{}}async function h(e,s,r,n){let c={method:e,headers:{"Content-Type":"application/json",...a.headers}};if(a.auth){const t=y();t&&(c.headers.Authorization=`Bearer ${t}`)}if(r!==void 0&&e!=="GET"){let t=typeof r=="object"&&r!==null?{...r}:r;if(a.auth&&typeof t=="object"&&t!==null){const u=y();u&&(t.formToken=u)}c.body=JSON.stringify(t)}if(n!=null&&n.headers&&Object.assign(c.headers,n.headers),n!=null&&n.params){const t=Object.entries(n.params).map(([u,m])=>`${encodeURIComponent(u)}=${encodeURIComponent(String(m))}`).join("&");s+=(s.includes("?")?"&":"?")+t}const d=a.baseUrl+s;c._url=d,c._requestId=++j;for(const t of k){const u=t(c);u&&(c=u)}const f=await fetch(d,c),g=f.headers.get("FreshToken");g&&I(g);const i=f.headers.get("Content-Type")??"";let l;i.includes("json")?l=await f.json():l=await f.text();let o={status:f.status,data:l,ok:f.ok,headers:f.headers,_requestId:c._requestId};for(const t of T){const u=t(o);u&&(o=u)}if(!f.ok)throw o;return o.data}const q={configure(e){Object.assign(a,e)},get(e,s){return h("GET",e,void 0,s)},post(e,s,r){return h("POST",e,s,r)},put(e,s,r){return h("PUT",e,s,r)},patch(e,s,r){return h("PATCH",e,s,r)},delete(e,s){return h("DELETE",e,void 0,s)},async upload(e,s,r){let n={method:"POST",headers:{...a.headers},body:s};if(delete n.headers["Content-Type"],delete n.headers["content-type"],a.auth){const o=y();o&&(n.headers.Authorization=`Bearer ${o}`)}if(r!=null&&r.headers&&Object.assign(n.headers,r.headers),r!=null&&r.params){const o=Object.entries(r.params).map(([t,u])=>`${encodeURIComponent(t)}=${encodeURIComponent(String(u))}`).join("&");e+=(e.includes("?")?"&":"?")+o}const c=a.baseUrl+e;n._url=c,n._requestId=++j;for(const o of k){const t=o(n);t&&(n=t)}const d=await fetch(c,n),f=d.headers.get("FreshToken");f&&I(f);const g=d.headers.get("Content-Type")??"";let i;g.includes("json")?i=await d.json():i=await d.text();let l={status:d.status,data:i,ok:d.ok,headers:d.headers,_requestId:n._requestId};for(const o of T){const t=o(l);t&&(l=t)}if(!d.ok)throw l;return l.data},intercept(e,s){e==="request"?k.push(s):T.push(s)},_reset(){a.baseUrl="",a.auth=!1,a.tokenKey="tina4_token",a.headers={},k.length=0,T.length=0}};exports.api=q;
package/dist/api.es.js CHANGED
@@ -1,74 +1,74 @@
1
- const s = {
1
+ const a = {
2
2
  baseUrl: "",
3
3
  auth: !1,
4
4
  tokenKey: "tina4_token",
5
5
  headers: {}
6
- }, h = [], d = [];
6
+ }, g = [], T = [];
7
7
  let I = 0;
8
- function T() {
8
+ function y() {
9
9
  try {
10
- return localStorage.getItem(s.tokenKey);
10
+ return localStorage.getItem(a.tokenKey);
11
11
  } catch {
12
12
  return null;
13
13
  }
14
14
  }
15
15
  function j(e) {
16
16
  try {
17
- localStorage.setItem(s.tokenKey, e);
17
+ localStorage.setItem(a.tokenKey, e);
18
18
  } catch {
19
19
  }
20
20
  }
21
- async function l(e, t, r, c) {
22
- let o = {
21
+ async function h(e, s, r, n) {
22
+ let c = {
23
23
  method: e,
24
24
  headers: {
25
25
  "Content-Type": "application/json",
26
- ...s.headers
26
+ ...a.headers
27
27
  }
28
28
  };
29
- if (s.auth) {
30
- const n = T();
31
- n && (o.headers.Authorization = `Bearer ${n}`);
29
+ if (a.auth) {
30
+ const t = y();
31
+ t && (c.headers.Authorization = `Bearer ${t}`);
32
32
  }
33
33
  if (r !== void 0 && e !== "GET") {
34
- let n = typeof r == "object" && r !== null ? { ...r } : r;
35
- if (s.auth && typeof n == "object" && n !== null) {
36
- const a = T();
37
- a && (n.formToken = a);
34
+ let t = typeof r == "object" && r !== null ? { ...r } : r;
35
+ if (a.auth && typeof t == "object" && t !== null) {
36
+ const u = y();
37
+ u && (t.formToken = u);
38
38
  }
39
- o.body = JSON.stringify(n);
39
+ c.body = JSON.stringify(t);
40
40
  }
41
- if (c != null && c.headers && Object.assign(o.headers, c.headers), c != null && c.params) {
42
- const n = Object.entries(c.params).map(([a, y]) => `${encodeURIComponent(a)}=${encodeURIComponent(String(y))}`).join("&");
43
- t += (t.includes("?") ? "&" : "?") + n;
41
+ if (n != null && n.headers && Object.assign(c.headers, n.headers), n != null && n.params) {
42
+ const t = Object.entries(n.params).map(([u, q]) => `${encodeURIComponent(u)}=${encodeURIComponent(String(q))}`).join("&");
43
+ s += (s.includes("?") ? "&" : "?") + t;
44
44
  }
45
- const g = s.baseUrl + t;
46
- o._url = g, o._requestId = ++I;
47
- for (const n of h) {
48
- const a = n(o);
49
- a && (o = a);
45
+ const d = a.baseUrl + s;
46
+ c._url = d, c._requestId = ++I;
47
+ for (const t of g) {
48
+ const u = t(c);
49
+ u && (c = u);
50
50
  }
51
- const u = await fetch(g, o), k = u.headers.get("FreshToken");
51
+ const f = await fetch(d, c), k = f.headers.get("FreshToken");
52
52
  k && j(k);
53
- const p = u.headers.get("Content-Type") ?? "";
54
- let i;
55
- p.includes("json") ? i = await u.json() : i = await u.text();
56
- let f = {
57
- status: u.status,
58
- data: i,
59
- ok: u.ok,
60
- headers: u.headers,
61
- _requestId: o._requestId
53
+ const i = f.headers.get("Content-Type") ?? "";
54
+ let l;
55
+ i.includes("json") ? l = await f.json() : l = await f.text();
56
+ let o = {
57
+ status: f.status,
58
+ data: l,
59
+ ok: f.ok,
60
+ headers: f.headers,
61
+ _requestId: c._requestId
62
62
  };
63
- for (const n of d) {
64
- const a = n(f);
65
- a && (f = a);
63
+ for (const t of T) {
64
+ const u = t(o);
65
+ u && (o = u);
66
66
  }
67
- if (!u.ok)
68
- throw f;
69
- return f.data;
67
+ if (!f.ok)
68
+ throw o;
69
+ return o.data;
70
70
  }
71
- const q = {
71
+ const m = {
72
72
  /**
73
73
  * Configure the API client. Call once at app startup.
74
74
  *
@@ -81,7 +81,7 @@ const q = {
81
81
  * });
82
82
  */
83
83
  configure(e) {
84
- Object.assign(s, e);
84
+ Object.assign(a, e);
85
85
  },
86
86
  /**
87
87
  * HTTP GET request.
@@ -90,8 +90,8 @@ const q = {
90
90
  * @example
91
91
  * const data = await api.get('/products', { params: { page: 2, limit: 20 } });
92
92
  */
93
- get(e, t) {
94
- return l("GET", e, void 0, t);
93
+ get(e, s) {
94
+ return h("GET", e, void 0, s);
95
95
  },
96
96
  /**
97
97
  * HTTP POST request.
@@ -101,20 +101,80 @@ const q = {
101
101
  * @example
102
102
  * await api.post('/users', { name: 'Alice', role: 'admin' });
103
103
  */
104
- post(e, t, r) {
105
- return l("POST", e, t, r);
104
+ post(e, s, r) {
105
+ return h("POST", e, s, r);
106
106
  },
107
107
  /** HTTP PUT — full replace. */
108
- put(e, t, r) {
109
- return l("PUT", e, t, r);
108
+ put(e, s, r) {
109
+ return h("PUT", e, s, r);
110
110
  },
111
111
  /** HTTP PATCH — partial update. */
112
- patch(e, t, r) {
113
- return l("PATCH", e, t, r);
112
+ patch(e, s, r) {
113
+ return h("PATCH", e, s, r);
114
114
  },
115
115
  /** HTTP DELETE. */
116
- delete(e, t) {
117
- return l("DELETE", e, void 0, t);
116
+ delete(e, s) {
117
+ return h("DELETE", e, void 0, s);
118
+ },
119
+ /**
120
+ * Upload files via FormData (multipart/form-data).
121
+ *
122
+ * Unlike `post()`, this does NOT JSON-stringify the body or set
123
+ * Content-Type — the browser sets the multipart boundary automatically.
124
+ * Auth uses the Bearer token header (formToken cannot be injected into FormData).
125
+ *
126
+ * @param path - API path relative to `baseUrl`.
127
+ * @param formData - A FormData instance containing files and fields.
128
+ * @param options - `{ params, headers }` — query string params and per-request headers.
129
+ *
130
+ * @example
131
+ * const form = new FormData();
132
+ * form.append('avatar', fileInput.files[0]);
133
+ * form.append('name', 'Alice');
134
+ * const result = await api.upload('/users/avatar', form);
135
+ */
136
+ async upload(e, s, r) {
137
+ let n = {
138
+ method: "POST",
139
+ headers: {
140
+ ...a.headers
141
+ // Do NOT set Content-Type — browser sets it with multipart boundary
142
+ },
143
+ body: s
144
+ };
145
+ if (delete n.headers["Content-Type"], delete n.headers["content-type"], a.auth) {
146
+ const o = y();
147
+ o && (n.headers.Authorization = `Bearer ${o}`);
148
+ }
149
+ if (r != null && r.headers && Object.assign(n.headers, r.headers), r != null && r.params) {
150
+ const o = Object.entries(r.params).map(([t, u]) => `${encodeURIComponent(t)}=${encodeURIComponent(String(u))}`).join("&");
151
+ e += (e.includes("?") ? "&" : "?") + o;
152
+ }
153
+ const c = a.baseUrl + e;
154
+ n._url = c, n._requestId = ++I;
155
+ for (const o of g) {
156
+ const t = o(n);
157
+ t && (n = t);
158
+ }
159
+ const d = await fetch(c, n), f = d.headers.get("FreshToken");
160
+ f && j(f);
161
+ const k = d.headers.get("Content-Type") ?? "";
162
+ let i;
163
+ k.includes("json") ? i = await d.json() : i = await d.text();
164
+ let l = {
165
+ status: d.status,
166
+ data: i,
167
+ ok: d.ok,
168
+ headers: d.headers,
169
+ _requestId: n._requestId
170
+ };
171
+ for (const o of T) {
172
+ const t = o(l);
173
+ t && (l = t);
174
+ }
175
+ if (!d.ok)
176
+ throw l;
177
+ return l.data;
118
178
  },
119
179
  /**
120
180
  * Register a request or response interceptor.
@@ -130,14 +190,14 @@ const q = {
130
190
  * if (res.status === 401) navigate('/login');
131
191
  * });
132
192
  */
133
- intercept(e, t) {
134
- e === "request" ? h.push(t) : d.push(t);
193
+ intercept(e, s) {
194
+ e === "request" ? g.push(s) : T.push(s);
135
195
  },
136
196
  /** @internal Reset state (for tests). */
137
197
  _reset() {
138
- s.baseUrl = "", s.auth = !1, s.tokenKey = "tina4_token", s.headers = {}, h.length = 0, d.length = 0;
198
+ a.baseUrl = "", a.auth = !1, a.tokenKey = "tina4_token", a.headers = {}, g.length = 0, T.length = 0;
139
199
  }
140
200
  };
141
201
  export {
142
- q as api
202
+ m as api
143
203
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tina4js",
3
- "version": "1.0.13",
4
- "description": "Sub-3KB reactive framework — signals, web components, routing, PWA",
3
+ "version": "1.0.15",
4
+ "description": "1.5KB core gzipped, reactive framework — signals, web components, routing, PWA",
5
5
  "type": "module",
6
6
  "main": "dist/tina4.cjs.js",
7
7
  "module": "dist/tina4.es.js",
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "sideEffects": false,
41
41
  "bin": {
42
- "tina4": "./bin/tina4.js"
42
+ "tina4js": "./bin/tina4.js"
43
43
  },
44
44
  "files": [
45
45
  "dist/",
package/readme.md CHANGED
@@ -3,10 +3,10 @@
3
3
  </p>
4
4
 
5
5
  <h1 align="center">tina4-js</h1>
6
- <h3 align="center">This is not a framework</h3>
6
+ <h3 align="center">The Intelligent Native Application 4ramework</h3>
7
7
 
8
8
  <p align="center">
9
- Sub-3KB reactive frontend. Signals. Web Components. Zero dependencies.
9
+ Sub-3KB core, reactive frontend. Signals. Web Components. Zero dependencies.
10
10
  </p>
11
11
 
12
12
  <p align="center">
@@ -294,7 +294,7 @@ npm run dev # dev server with HMR
294
294
  - **Fix:** All `@event` handlers auto-wrapped in `batch()` -- one re-render per handler, no mid-event DOM rebuilds
295
295
 
296
296
  ### 1.0.8
297
- - Added `--css` flag to `tina4 create` for optional tina4-css integration
297
+ - Added `--css` flag to `tina4js create` for optional tina4-css integration
298
298
  - Added gallery of 9 real-world examples
299
299
 
300
300
  ### 1.0.7
@@ -311,4 +311,4 @@ npm run dev # dev server with HMR
311
311
 
312
312
  MIT
313
313
 
314
- *tina4-js — This is not a framework. [tina4.com](https://tina4.com)*
314
+ *tina4-js — The Intelligent Native Application 4ramework. [tina4.com](https://tina4.com)*
@@ -1,105 +0,0 @@
1
- /**
2
- * Tina4 API — Fetch wrapper with auth token management.
3
- *
4
- * Compatible with tina4-php and tina4-python backends:
5
- * - Sends Authorization: Bearer <token>
6
- * - Reads FreshToken response header for token rotation
7
- * - Sends formToken in POST/PUT/PATCH/DELETE bodies
8
- */
9
- export interface ApiConfig {
10
- baseUrl: string;
11
- auth: boolean;
12
- tokenKey: string;
13
- headers: Record<string, string>;
14
- }
15
- export interface ApiResponse<T = unknown> {
16
- status: number;
17
- data: T;
18
- ok: boolean;
19
- headers: Headers;
20
- /** @internal Used by debug tracker for request/response correlation. */
21
- _requestId?: number;
22
- }
23
- export type RequestInterceptor = (config: RequestInit & {
24
- headers: Record<string, string>;
25
- }) => (RequestInit & {
26
- headers: Record<string, string>;
27
- }) | void;
28
- export type ResponseInterceptor = (response: ApiResponse) => ApiResponse | void;
29
- export interface RequestOptions {
30
- headers?: Record<string, string>;
31
- params?: Record<string, string | number | boolean>;
32
- }
33
- /**
34
- * HTTP client pre-configured for tina4-php / tina4-python backends.
35
- *
36
- * Features:
37
- * - Automatic `Authorization: Bearer <token>` header when `auth: true`
38
- * - Token rotation via `FreshToken` response header
39
- * - `formToken` injected into POST/PUT/PATCH/DELETE bodies for CSRF protection
40
- * - Per-request `headers` and `params` via `RequestOptions`
41
- * - Request/response interceptors
42
- *
43
- * @example
44
- * api.configure({ baseUrl: 'https://api.example.com', auth: true });
45
- *
46
- * const users = await api.get('/users');
47
- * const user = await api.get('/users', { params: { id: 42 } });
48
- * await api.post('/users', { name: 'Alice' });
49
- * await api.delete('/users/1');
50
- */
51
- export declare const api: {
52
- /**
53
- * Configure the API client. Call once at app startup.
54
- *
55
- * @example
56
- * api.configure({
57
- * baseUrl: 'https://api.example.com',
58
- * auth: true,
59
- * tokenKey: 'my_token', // localStorage key (default: 'tina4_token')
60
- * headers: { 'X-App': '1' }, // default headers on every request
61
- * });
62
- */
63
- configure(c: Partial<ApiConfig>): void;
64
- /**
65
- * HTTP GET request.
66
- * @param path - API path relative to `baseUrl`.
67
- * @param options - `{ params, headers }` — query string params and per-request headers.
68
- * @example
69
- * const data = await api.get('/products', { params: { page: 2, limit: 20 } });
70
- */
71
- get<T = unknown>(path: string, options?: RequestOptions): Promise<T>;
72
- /**
73
- * HTTP POST request.
74
- * @param path - API path.
75
- * @param body - Request body (serialised as JSON).
76
- * @param options - `{ params, headers }`.
77
- * @example
78
- * await api.post('/users', { name: 'Alice', role: 'admin' });
79
- */
80
- post<T = unknown>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
81
- /** HTTP PUT — full replace. */
82
- put<T = unknown>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
83
- /** HTTP PATCH — partial update. */
84
- patch<T = unknown>(path: string, body?: unknown, options?: RequestOptions): Promise<T>;
85
- /** HTTP DELETE. */
86
- delete<T = unknown>(path: string, options?: RequestOptions): Promise<T>;
87
- /**
88
- * Register a request or response interceptor.
89
- *
90
- * @example
91
- * // Add a custom header to every request
92
- * api.intercept('request', (config) => {
93
- * config.headers['X-Client'] = 'my-app';
94
- * });
95
- *
96
- * // Redirect to login on 401
97
- * api.intercept('response', (res) => {
98
- * if (res.status === 401) navigate('/login');
99
- * });
100
- */
101
- intercept(type: "request" | "response", fn: RequestInterceptor | ResponseInterceptor): void;
102
- /** @internal Reset state (for tests). */
103
- _reset(): void;
104
- };
105
- //# sourceMappingURL=fetch.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/api/fetch.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,OAAO;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,CAAC,CAAC;IACR,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,WAAW,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,KAAK,CAAC,WAAW,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC,GAAG,IAAI,CAAC;AAC3J,MAAM,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,WAAW,KAAK,WAAW,GAAG,IAAI,CAAC;AA+BhF,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;CACpD;AA+FD;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,GAAG;IACd;;;;;;;;;;OAUG;iBACU,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI;IAItC;;;;;;OAMG;QACC,CAAC,kBAAkB,MAAM,YAAY,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAIpE;;;;;;;OAOG;SACE,CAAC,kBAAkB,MAAM,SAAS,OAAO,YAAY,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAIrF,+BAA+B;QAC3B,CAAC,kBAAkB,MAAM,SAAS,OAAO,YAAY,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAIpF,mCAAmC;UAC7B,CAAC,kBAAkB,MAAM,SAAS,OAAO,YAAY,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAItF,mBAAmB;WACZ,CAAC,kBAAkB,MAAM,YAAY,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAIvE;;;;;;;;;;;;;OAaG;oBACa,SAAS,GAAG,UAAU,MAAM,kBAAkB,GAAG,mBAAmB,GAAG,IAAI;IAQ3F,yCAAyC;cAC/B,IAAI;CAQf,CAAC"}
@@ -1,6 +0,0 @@
1
- /**
2
- * tina4js/api — Fetch wrapper with auth token management.
3
- */
4
- export { api } from './fetch';
5
- export type { ApiConfig, ApiResponse, RequestOptions, RequestInterceptor, ResponseInterceptor } from './fetch';
6
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAC9B,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC"}
@@ -1,59 +0,0 @@
1
- /**
2
- * Tina4 Component — Base class for web components.
3
- *
4
- * Extends HTMLElement with reactive props, lifecycle hooks,
5
- * optional Shadow DOM, and scoped styles.
6
- */
7
- import { type Signal } from './signal';
8
- /** @internal Called when a Tina4Element is connected to the DOM. */
9
- export declare let __debugComponentMount: ((el: Tina4Element) => void) | null;
10
- /** @internal Called when a Tina4Element is disconnected from the DOM. */
11
- export declare let __debugComponentUnmount: ((el: Tina4Element) => void) | null;
12
- /** @internal Set the debug hooks. */
13
- export declare function __setDebugComponentHooks(onMount: typeof __debugComponentMount, onUnmount: typeof __debugComponentUnmount): void;
14
- export type PropType = typeof String | typeof Number | typeof Boolean;
15
- export declare abstract class Tina4Element extends HTMLElement {
16
- /** Declare reactive props and their types. Override in subclass. */
17
- static props: Record<string, PropType>;
18
- /** Scoped CSS styles. Override in subclass. */
19
- static styles: string;
20
- /** Use Shadow DOM (true) or light DOM (false). Override in subclass. */
21
- static shadow: boolean;
22
- /** Internal reactive prop signals. */
23
- private _props;
24
- /** The render root (shadow or this). */
25
- private _root;
26
- /** Track if we've rendered. */
27
- private _rendered;
28
- static get observedAttributes(): string[];
29
- constructor();
30
- connectedCallback(): void;
31
- disconnectedCallback(): void;
32
- attributeChangedCallback(name: string, _old: string | null, value: string | null): void;
33
- /**
34
- * Get a reactive signal for a declared prop.
35
- *
36
- * ```ts
37
- * render() {
38
- * return html`<span>${this.prop('name')}</span>`;
39
- * }
40
- * ```
41
- */
42
- prop<T = unknown>(name: string): Signal<T>;
43
- /**
44
- * Dispatch a custom event from this component.
45
- *
46
- * ```ts
47
- * this.emit('activate', { detail: 42 });
48
- * ```
49
- */
50
- emit(name: string, init?: CustomEventInit): void;
51
- /** Called after first render. */
52
- onMount(): void;
53
- /** Called when removed from DOM. */
54
- onUnmount(): void;
55
- /** Return DOM content. Override in subclass. */
56
- abstract render(): DocumentFragment | Node | null;
57
- private _coerce;
58
- }
59
- //# sourceMappingURL=component.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../src/core/component.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAU,KAAK,MAAM,EAAE,MAAM,UAAU,CAAC;AAI/C,oEAAoE;AACpE,eAAO,IAAI,qBAAqB,EAAE,CAAC,CAAC,EAAE,EAAE,YAAY,KAAK,IAAI,CAAC,GAAG,IAAW,CAAC;AAC7E,yEAAyE;AACzE,eAAO,IAAI,uBAAuB,EAAE,CAAC,CAAC,EAAE,EAAE,YAAY,KAAK,IAAI,CAAC,GAAG,IAAW,CAAC;AAC/E,qCAAqC;AACrC,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,OAAO,qBAAqB,EACrC,SAAS,EAAE,OAAO,uBAAuB,QAI1C;AAED,MAAM,MAAM,QAAQ,GAAG,OAAO,MAAM,GAAG,OAAO,MAAM,GAAG,OAAO,OAAO,CAAC;AAEtE,8BAAsB,YAAa,SAAQ,WAAW;IACpD,oEAAoE;IACpE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAM;IAE5C,+CAA+C;IAC/C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM;IAE3B,wEAAwE;IACxE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAQ;IAE9B,sCAAsC;IACtC,OAAO,CAAC,MAAM,CAAuC;IAErD,wCAAwC;IACxC,OAAO,CAAC,KAAK,CAA2B;IAExC,+BAA+B;IAC/B,OAAO,CAAC,SAAS,CAAS;IAE1B,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAExC;;IAaD,iBAAiB,IAAI,IAAI;IAuBzB,oBAAoB,IAAI,IAAI;IAK5B,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAQvF;;;;;;;;OAQG;IACH,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;IAO1C;;;;;;OAMG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,IAAI;IAUhD,iCAAiC;IACjC,OAAO,IAAI,IAAI;IAEf,oCAAoC;IACpC,SAAS,IAAI,IAAI;IAEjB,gDAAgD;IAChD,QAAQ,CAAC,MAAM,IAAI,gBAAgB,GAAG,IAAI,GAAG,IAAI;IAIjD,OAAO,CAAC,OAAO;CAKhB"}
@@ -1,37 +0,0 @@
1
- /**
2
- * Tina4 HTML — Tagged template literal renderer.
3
- *
4
- * html`<div>${value}</div>` returns real DOM nodes (DocumentFragment).
5
- * When a signal is interpolated, the DOM updates surgically — no diffing.
6
- */
7
- /**
8
- * Tagged template literal renderer — builds real DOM nodes with surgical reactive updates.
9
- *
10
- * Interpolated values are bound as follows:
11
- * - `${signal}` → reactive text node, updates in place when the signal changes
12
- * - `${() => expr}` → reactive block, re-renders when any signal read inside changes
13
- * - `${fragment}` → inserts a DocumentFragment (nested `html\`\``)
14
- * - `${array}` → renders each item as nodes
15
- * - `${value}` → static text node (escaped — XSS-safe)
16
- *
17
- * Attribute binding syntax (in tag attributes):
18
- * - `.innerHTML=${val}` → sets DOM property (use for raw HTML / inline SVG)
19
- * - `.value=${signal}` → reactive DOM property binding
20
- * - `?disabled=${sig}` → boolean attribute — added/removed reactively
21
- * - `@click=${fn}` → event listener
22
- *
23
- * **Important:** `${svgString}` in content position renders as escaped text.
24
- * To inject raw HTML or SVG, use: `<div .innerHTML=${svgString}></div>`
25
- *
26
- * @param strings - Template string parts (static, cached by identity).
27
- * @param values - Interpolated values.
28
- * @returns A DocumentFragment ready to append to the DOM.
29
- *
30
- * @example
31
- * const name = signal('World');
32
- * const frag = html`<h1>Hello, ${name}!</h1>`;
33
- * document.body.appendChild(frag);
34
- * name.value = 'Tina4'; // DOM updates automatically
35
- */
36
- export declare function html(strings: TemplateStringsArray, ...values: unknown[]): DocumentFragment;
37
- //# sourceMappingURL=html.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/core/html.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAiC1F"}
@@ -1,9 +0,0 @@
1
- /**
2
- * tina4js/core — Reactive primitives, HTML renderer, and web component base.
3
- */
4
- export { signal, computed, effect, batch, isSignal } from './signal';
5
- export type { Signal, ReadonlySignal } from './signal';
6
- export { html } from './html';
7
- export { Tina4Element } from './component';
8
- export type { PropType } from './component';
9
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACrE,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC"}
@@ -1,101 +0,0 @@
1
- /**
2
- * Tina4 Signals — Reactive state primitives.
3
- *
4
- * signal(value) — create a reactive value
5
- * computed(fn) — derive a value that auto-tracks dependencies
6
- * effect(fn) — run a side-effect that auto-tracks dependencies
7
- * batch(fn) — batch multiple signal updates into one notification
8
- */
9
- /** @internal Start collecting effect disposers (used by router). */
10
- export declare function _setEffectCollector(collector: (() => void)[] | null): void;
11
- /** @internal Read the current effect collector (used by html renderer). */
12
- export declare function _getEffectCollector(): (() => void)[] | null;
13
- /** @internal Called when a signal is created. */
14
- export declare let __debugSignalCreate: ((s: Signal<unknown>, label?: string) => void) | null;
15
- /** @internal Called when a signal value changes. */
16
- export declare let __debugSignalUpdate: ((s: Signal<unknown>, oldVal: unknown, newVal: unknown) => void) | null;
17
- /** @internal Set the debug hooks. */
18
- export declare function __setDebugSignalHooks(onCreate: typeof __debugSignalCreate, onUpdate: typeof __debugSignalUpdate): void;
19
- export interface Signal<T> {
20
- value: T;
21
- /** @internal */
22
- readonly _t4: true;
23
- /** @internal subscribe directly (used by html renderer) */
24
- _subscribe(fn: () => void): () => void;
25
- /** @internal read without tracking */
26
- peek(): T;
27
- }
28
- export interface ReadonlySignal<T> {
29
- readonly value: T;
30
- /** @internal */
31
- readonly _t4: true;
32
- /** @internal */
33
- _subscribe(fn: () => void): () => void;
34
- peek(): T;
35
- }
36
- /**
37
- * Create a reactive signal — a value that notifies subscribers when it changes.
38
- *
39
- * @param initial - The initial value.
40
- * @param label - Optional debug label shown in the debug overlay.
41
- * @returns A signal whose `.value` getter/setter is reactive.
42
- *
43
- * @example
44
- * const count = signal(0);
45
- * count.value; // read: 0
46
- * count.value = 5; // write: triggers all subscribers
47
- *
48
- * const name = signal('Alice', 'userName'); // labelled for debug overlay
49
- */
50
- export declare function signal<T>(initial: T, label?: string): Signal<T>;
51
- /**
52
- * Create a derived signal that auto-tracks its dependencies.
53
- * Re-computes whenever any signal read inside `fn` changes.
54
- * The result is read-only — writing throws.
55
- *
56
- * @param fn - Pure function that reads signals and returns a derived value.
57
- * @returns A read-only signal.
58
- *
59
- * @example
60
- * const price = signal(10);
61
- * const qty = signal(3);
62
- * const total = computed(() => price.value * qty.value);
63
- * total.value; // 30 — updates automatically when price or qty change
64
- */
65
- export declare function computed<T>(fn: () => T): ReadonlySignal<T>;
66
- /**
67
- * Run a side-effect that auto-tracks signal dependencies.
68
- * Runs immediately, then re-runs whenever a dependency changes.
69
- * If the effect throws, sibling effects still run; the first error is re-thrown
70
- * after all subscribers have been notified.
71
- *
72
- * @param fn - The side-effect function. Reads signals to establish tracking.
73
- * @returns A `dispose` function — call it to stop the effect.
74
- *
75
- * @example
76
- * const count = signal(0);
77
- * const stop = effect(() => {
78
- * console.log('count is', count.value);
79
- * });
80
- * // logs immediately, then on every count change
81
- * stop(); // unsubscribe
82
- */
83
- export declare function effect(fn: () => void): () => void;
84
- /**
85
- * Batch multiple signal updates into a single notification pass.
86
- * Subscribers are notified once after `fn` completes, not after each write.
87
- *
88
- * @param fn - Function containing one or more signal writes.
89
- *
90
- * @example
91
- * const a = signal(1);
92
- * const b = signal(2);
93
- * batch(() => {
94
- * a.value = 10;
95
- * b.value = 20;
96
- * }); // effects run once, not twice
97
- */
98
- export declare function batch(fn: () => void): void;
99
- /** Check if a value is a tina4 signal. */
100
- export declare function isSignal(value: unknown): value is Signal<unknown>;
101
- //# sourceMappingURL=signal.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"signal.d.ts","sourceRoot":"","sources":["../../src/core/signal.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,oEAAoE;AACpE,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,CAAC,MAAM,IAAI,CAAC,EAAE,GAAG,IAAI,GAAG,IAAI,CAE1E;AAED,2EAA2E;AAC3E,wBAAgB,mBAAmB,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,GAAG,IAAI,CAE3D;AAID,iDAAiD;AACjD,eAAO,IAAI,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAW,CAAC;AAC7F,oDAAoD;AACpD,eAAO,IAAI,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAW,CAAC;AAC/G,qCAAqC;AACrC,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,OAAO,mBAAmB,EACpC,QAAQ,EAAE,OAAO,mBAAmB,QAIrC;AAUD,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB,KAAK,EAAE,CAAC,CAAC;IACT,gBAAgB;IAChB,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;IACnB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;IACvC,sCAAsC;IACtC,IAAI,IAAI,CAAC,CAAC;CACX;AAED,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAClB,gBAAgB;IAChB,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;IACnB,gBAAgB;IAChB,UAAU,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;IACvC,IAAI,IAAI,CAAC,CAAC;CACX;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAoD/D;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CA2B1D;AAID;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAgCjD;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAgB1C;AAID,0CAA0C;AAC1C,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,OAAO,CAAC,CAEjE"}
@@ -1,17 +0,0 @@
1
- /**
2
- * tina4js/debug — Developer debug overlay.
3
- *
4
- * Import this module to enable the debug overlay:
5
- * import 'tina4js/debug';
6
- *
7
- * Or conditionally:
8
- * if (import.meta.env.DEV) import('tina4js/debug');
9
- *
10
- * Toggle: Ctrl+Shift+D
11
- */
12
- /**
13
- * Enable the debug overlay. Called automatically on import,
14
- * or can be called explicitly.
15
- */
16
- export declare function enableDebug(): void;
17
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/debug/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAaH;;;GAGG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAsDlC"}
@@ -1,25 +0,0 @@
1
- /**
2
- * Debug Overlay — Shadow DOM custom element with tabbed panel UI.
3
- */
4
- export declare class Tina4Debug extends HTMLElement {
5
- private _shadow;
6
- private _visible;
7
- private _activeTab;
8
- private _refreshTimer;
9
- constructor();
10
- connectedCallback(): void;
11
- disconnectedCallback(): void;
12
- toggle(): void;
13
- show(): void;
14
- hide(): void;
15
- private _startAutoRefresh;
16
- private _stopAutoRefresh;
17
- private _switchTab;
18
- private _getTabContent;
19
- private _renderBody;
20
- private _updateTabCounts;
21
- private _render;
22
- }
23
- /** Register the custom element. Call before creating instances. */
24
- export declare function registerDebugElement(): void;
25
- //# sourceMappingURL=overlay.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../src/debug/overlay.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH,qBAAa,UAAW,SAAQ,WAAW;IACzC,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,aAAa,CAAuB;;IAO5C,iBAAiB;IAKjB,oBAAoB;IAIpB,MAAM;IAKN,IAAI;IAKJ,IAAI;IAKJ,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,OAAO;CAsDhB;AAED,mEAAmE;AACnE,wBAAgB,oBAAoB,IAAI,IAAI,CAI3C"}
@@ -1,5 +0,0 @@
1
- /**
2
- * API Panel — Request/response log.
3
- */
4
- export declare function renderApiPanel(): string;
5
- //# sourceMappingURL=api.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/debug/panels/api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAuBH,wBAAgB,cAAc,IAAI,MAAM,CAyBvC"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Components Panel — Mounted Tina4Elements inspector.
3
- */
4
- export declare function renderComponentsPanel(): string;
5
- //# sourceMappingURL=components.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../src/debug/panels/components.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,wBAAgB,qBAAqB,IAAI,MAAM,CAsB9C"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Routes Panel — Registered routes and navigation history.
3
- */
4
- export declare function renderRoutesPanel(): string;
5
- //# sourceMappingURL=routes.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/debug/panels/routes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAeH,wBAAgB,iBAAiB,IAAI,MAAM,CA8C1C"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Signals Panel — Live signal inspector.
3
- */
4
- export declare function renderSignalsPanel(): string;
5
- //# sourceMappingURL=signals.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"signals.d.ts","sourceRoot":"","sources":["../../../src/debug/panels/signals.ts"],"names":[],"mappings":"AAAA;;GAEG;AAgBH,wBAAgB,kBAAkB,IAAI,MAAM,CAuB3C"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Debug Overlay Styles — Scoped inside Shadow DOM.
3
- */
4
- export declare const debugStyles = "\n:host {\n all: initial;\n position: fixed;\n bottom: 0;\n right: 0;\n z-index: 999999;\n font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', monospace;\n font-size: 12px;\n color: #e0e0e0;\n line-height: 1.4;\n}\n\n* { box-sizing: border-box; }\n\n.t4-debug {\n width: 480px;\n max-height: 420px;\n background: #1a1a2e;\n border: 1px solid #333;\n border-radius: 8px 0 0 0;\n display: flex;\n flex-direction: column;\n box-shadow: -4px -4px 20px rgba(0,0,0,0.5);\n}\n\n.t4-debug.collapsed {\n max-height: none;\n}\n\n.t4-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 12px;\n background: #16213e;\n border-bottom: 1px solid #333;\n border-radius: 8px 0 0 0;\n cursor: move;\n user-select: none;\n}\n\n.t4-logo {\n font-weight: 700;\n font-size: 13px;\n color: #00d4ff;\n letter-spacing: 0.5px;\n}\n\n.t4-badge {\n font-size: 10px;\n padding: 1px 6px;\n border-radius: 4px;\n background: #0f3460;\n color: #00d4ff;\n margin-left: 8px;\n}\n\n.t4-header-right {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.t4-close {\n background: none;\n border: none;\n color: #888;\n cursor: pointer;\n font-size: 16px;\n padding: 2px 6px;\n border-radius: 4px;\n}\n.t4-close:hover { color: #ff6b6b; background: rgba(255,107,107,0.1); }\n\n.t4-tabs {\n display: flex;\n border-bottom: 1px solid #333;\n background: #16213e;\n}\n\n.t4-tab {\n flex: 1;\n padding: 6px 8px;\n background: none;\n border: none;\n color: #888;\n cursor: pointer;\n font-size: 11px;\n font-family: inherit;\n border-bottom: 2px solid transparent;\n transition: all 0.15s;\n}\n.t4-tab:hover { color: #ccc; background: rgba(255,255,255,0.03); }\n.t4-tab.active {\n color: #00d4ff;\n border-bottom-color: #00d4ff;\n background: rgba(0,212,255,0.05);\n}\n\n.t4-tab-count {\n font-size: 10px;\n color: #666;\n margin-left: 4px;\n}\n\n.t4-body {\n flex: 1;\n overflow-y: auto;\n padding: 8px;\n min-height: 200px;\n max-height: 340px;\n}\n\n.t4-body::-webkit-scrollbar { width: 6px; }\n.t4-body::-webkit-scrollbar-track { background: transparent; }\n.t4-body::-webkit-scrollbar-thumb { background: #333; border-radius: 3px; }\n\n/* Panel table styles */\ntable {\n width: 100%;\n border-collapse: collapse;\n}\n\nth {\n text-align: left;\n padding: 4px 8px;\n color: #888;\n font-weight: 500;\n font-size: 10px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n border-bottom: 1px solid #2a2a3e;\n position: sticky;\n top: 0;\n background: #1a1a2e;\n}\n\ntd {\n padding: 3px 8px;\n border-bottom: 1px solid rgba(255,255,255,0.03);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 150px;\n}\n\ntr:hover td { background: rgba(255,255,255,0.02); }\n\n/* Value displays */\n.val-string { color: #a8e6cf; }\n.val-number { color: #ffd3a5; }\n.val-boolean { color: #ff8b94; }\n.val-object { color: #b8b5ff; }\n.val-null { color: #666; font-style: italic; }\n\n/* Status badges */\n.status-ok { color: #66bb6a; }\n.status-err { color: #ff6b6b; }\n.status-pending { color: #ffa726; }\n\n/* Route pattern */\n.route-pattern { color: #b8b5ff; }\n.route-param { color: #ffd3a5; }\n\n/* Duration */\n.duration { color: #888; font-size: 11px; }\n.duration.fast { color: #66bb6a; }\n.duration.slow { color: #ffa726; }\n.duration.very-slow { color: #ff6b6b; }\n\n/* Empty state */\n.t4-empty {\n text-align: center;\n color: #555;\n padding: 32px 16px;\n font-size: 12px;\n}\n\n/* Collapsed mini-badge */\n.t4-mini {\n position: fixed;\n bottom: 12px;\n right: 12px;\n background: #1a1a2e;\n border: 1px solid #333;\n border-radius: 8px;\n padding: 6px 12px;\n cursor: pointer;\n font-family: inherit;\n font-size: 11px;\n color: #00d4ff;\n box-shadow: -2px -2px 10px rgba(0,0,0,0.3);\n z-index: 999999;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n.t4-mini:hover { background: #16213e; }\n\n.t4-mini-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: #66bb6a;\n}\n";
5
- //# sourceMappingURL=styles.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../src/debug/styles.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,WAAW,+9HA8MvB,CAAC"}
@@ -1,89 +0,0 @@
1
- /**
2
- * Debug Trackers — Data collection for signals, components, routes, and API.
3
- */
4
- import type { Signal } from '../core/signal';
5
- import type { Tina4Element } from '../core/component';
6
- import type { ChangeEvent } from '../router/router';
7
- export interface TrackedSignal {
8
- ref: WeakRef<Signal<unknown>>;
9
- label?: string;
10
- createdAt: number;
11
- updateCount: number;
12
- subs: WeakRef<Set<() => void>>;
13
- }
14
- export declare const signalTracker: {
15
- add(s: Signal<unknown>, label?: string): void;
16
- onUpdate(s: Signal<unknown>): void;
17
- getAll(): {
18
- label?: string;
19
- value: unknown;
20
- subscriberCount: number;
21
- updateCount: number;
22
- alive: boolean;
23
- }[];
24
- readonly count: number;
25
- };
26
- export interface TrackedComponent {
27
- ref: WeakRef<Tina4Element>;
28
- tagName: string;
29
- mountedAt: number;
30
- }
31
- export declare const componentTracker: {
32
- onMount(el: Tina4Element): void;
33
- onUnmount(el: Tina4Element): void;
34
- getAll(): {
35
- tagName: string;
36
- props: Record<string, unknown>;
37
- alive: boolean;
38
- }[];
39
- readonly count: number;
40
- };
41
- export interface RouteEntry {
42
- path: string;
43
- pattern: string;
44
- params: Record<string, string>;
45
- durationMs: number;
46
- timestamp: number;
47
- }
48
- declare let _getRoutesFn: (() => ReadonlyArray<{
49
- pattern: string;
50
- hasGuard: boolean;
51
- }>) | null;
52
- export declare const routeTracker: {
53
- /** Set the function that reads registered routes (avoids direct import from router). */
54
- setGetRoutes(fn: typeof _getRoutesFn): void;
55
- getRegisteredRoutes(): ReadonlyArray<{
56
- pattern: string;
57
- hasGuard: boolean;
58
- }>;
59
- onNavigate(event: ChangeEvent): void;
60
- getHistory(): readonly RouteEntry[];
61
- readonly count: number;
62
- };
63
- export interface ApiEntry {
64
- id: number;
65
- method: string;
66
- url: string;
67
- status?: number;
68
- durationMs?: number;
69
- hasAuth: boolean;
70
- timestamp: number;
71
- pending: boolean;
72
- error?: string;
73
- }
74
- export declare const apiTracker: {
75
- onRequest(config: RequestInit & {
76
- headers: Record<string, string>;
77
- _url?: string;
78
- _requestId?: number;
79
- }): void;
80
- onResponse(response: {
81
- status: number;
82
- ok: boolean;
83
- _requestId?: number;
84
- }): void;
85
- getLog(): readonly ApiEntry[];
86
- readonly count: number;
87
- };
88
- export {};
89
- //# sourceMappingURL=trackers.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"trackers.d.ts","sourceRoot":"","sources":["../../src/debug/trackers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAIpD,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;CAChC;AAID,eAAO,MAAM,aAAa;WACjB,MAAM,CAAC,OAAO,CAAC,UAAU,MAAM;gBAW1B,MAAM,CAAC,OAAO,CAAC;cASjB;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,EAAE;;CAsB7G,CAAC;AAIF,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,eAAO,MAAM,gBAAgB;gBACf,YAAY;kBAQV,YAAY;cAKhB;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,EAAE;;CAuBhF,CAAC;AAIF,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,QAAA,IAAI,YAAY,EAAE,CAAC,MAAM,aAAa,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC,GAAG,IAAW,CAAC;AAE9F,eAAO,MAAM,YAAY;IACvB,wFAAwF;qBACvE,OAAO,YAAY;2BAEb,aAAa,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;sBAG1D,WAAW;kBAWf,SAAS,UAAU,EAAE;;CAKpC,CAAC;AAIF,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAOD,eAAO,MAAM,UAAU;sBACH,WAAW,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;yBAezF;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;cAatE,SAAS,QAAQ,EAAE;;CAK9B,CAAC"}
package/dist/index.d.ts DELETED
@@ -1,19 +0,0 @@
1
- /**
2
- * tina4js — Sub-3KB reactive framework.
3
- *
4
- * Signals + tagged template rendering + web components + routing + API + PWA.
5
- */
6
- export { signal, computed, effect, batch, isSignal } from './core/signal';
7
- export type { Signal, ReadonlySignal } from './core/signal';
8
- export { html } from './core/html';
9
- export { Tina4Element } from './core/component';
10
- export type { PropType } from './core/component';
11
- export { route, navigate, router } from './router/router';
12
- export type { RouteParams, RouteHandler, RouteGuard, RouteConfig } from './router/router';
13
- export { api } from './api/fetch';
14
- export type { ApiConfig, ApiResponse, RequestOptions } from './api/fetch';
15
- export { pwa } from './pwa/pwa';
16
- export type { PWAConfig } from './pwa/pwa';
17
- export { ws } from './ws/ws';
18
- export type { SocketStatus, SocketOptions, ManagedSocket } from './ws/ws';
19
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC1E,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,YAAY,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGjD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC1D,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG1F,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG1E,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAChC,YAAY,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAG3C,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC"}
@@ -1,6 +0,0 @@
1
- /**
2
- * tina4js/pwa — Service worker and manifest generation.
3
- */
4
- export { pwa } from './pwa';
5
- export type { PWAConfig } from './pwa';
6
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pwa/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC"}
package/dist/pwa/pwa.d.ts DELETED
@@ -1,24 +0,0 @@
1
- /**
2
- * Tina4 PWA — Service worker registration and manifest generation.
3
- *
4
- * Optional module — tree-shaken away if not imported.
5
- */
6
- export interface PWAConfig {
7
- name: string;
8
- shortName?: string;
9
- themeColor?: string;
10
- backgroundColor?: string;
11
- display?: 'standalone' | 'fullscreen' | 'minimal-ui' | 'browser';
12
- icon?: string;
13
- cacheStrategy?: 'cache-first' | 'network-first' | 'stale-while-revalidate';
14
- precache?: string[];
15
- offlineRoute?: string;
16
- }
17
- export declare const pwa: {
18
- register(config: PWAConfig): void;
19
- /** Generate SW code as a string (for build tools that write sw.js to disk). */
20
- generateServiceWorker(config: PWAConfig): string;
21
- /** Generate manifest object (for build tools that write manifest.json to disk). */
22
- generateManifest(config: PWAConfig): object;
23
- };
24
- //# sourceMappingURL=pwa.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pwa.d.ts","sourceRoot":"","sources":["../../src/pwa/pwa.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,YAAY,GAAG,YAAY,GAAG,YAAY,GAAG,SAAS,CAAC;IACjE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,aAAa,GAAG,eAAe,GAAG,wBAAwB,CAAC;IAC3E,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAkFD,eAAO,MAAM,GAAG;qBACG,SAAS,GAAG,IAAI;IA6BjC,+EAA+E;kCACjD,SAAS,GAAG,MAAM;IAIhD,mFAAmF;6BAC1D,SAAS,GAAG,MAAM;CAG5C,CAAC"}
@@ -1,6 +0,0 @@
1
- /**
2
- * tina4js/router — Client-side routing.
3
- */
4
- export { route, navigate, router, _resetRouter } from './router';
5
- export type { RouteParams, RouteHandler, RouteGuard, RouteConfig } from './router';
6
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/router/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACjE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC"}
@@ -1,72 +0,0 @@
1
- /**
2
- * Tina4 Router — Client-side routing with history and hash modes.
3
- *
4
- * route(path, handler) — register a route
5
- * navigate(path) — programmatic navigation
6
- * router.start(config) — start the router
7
- */
8
- export type RouteParams = Record<string, string>;
9
- export type RouteHandler = (params: RouteParams) => unknown;
10
- export type RouteGuard = () => boolean | string;
11
- export interface RouteConfig {
12
- guard?: RouteGuard;
13
- handler: RouteHandler;
14
- }
15
- interface RouterConfig {
16
- target: string;
17
- mode?: 'history' | 'hash';
18
- }
19
- export type ChangeEvent = {
20
- path: string;
21
- params: RouteParams;
22
- pattern: string;
23
- durationMs: number;
24
- };
25
- type ChangeListener = (event: ChangeEvent) => void;
26
- /**
27
- * Register a route. Pattern is ALWAYS the first argument.
28
- *
29
- * Patterns support `{param}` segments — extracted and passed to the handler.
30
- * Use `'*'` to match any path (catch-all / 404 route).
31
- *
32
- * @param pattern - URL pattern, e.g. `'/'`, `'/users/{id}'`, `'*'`
33
- * @param handlerOrConfig - Handler function or `{ handler, guard }` config.
34
- *
35
- * @example
36
- * route('/', () => html`<h1>Home</h1>`);
37
- * route('/users/{id}', ({ id }) => html`<p>User: ${id}</p>`);
38
- * route('*', () => html`<h1>404</h1>`);
39
- *
40
- * // With a guard:
41
- * route('/admin', {
42
- * guard: () => isLoggedIn.value || '/login',
43
- * handler: () => html`<admin-panel></admin-panel>`,
44
- * });
45
- */
46
- export declare function route(pattern: string, handlerOrConfig: RouteHandler | RouteConfig): void;
47
- /**
48
- * Programmatically navigate to a path.
49
- *
50
- * @param path - The path to navigate to.
51
- * @param opts - `{ replace: true }` uses `history.replaceState` instead of `pushState`.
52
- *
53
- * @example
54
- * navigate('/dashboard');
55
- * navigate('/login', { replace: true }); // no back-button entry
56
- */
57
- export declare function navigate(path: string, opts?: {
58
- replace?: boolean;
59
- }): void;
60
- export declare const router: {
61
- start(config: RouterConfig): void;
62
- on(event: "change", fn: ChangeListener): () => void;
63
- };
64
- /** @internal Read-only access to registered routes (for debug overlay). */
65
- export declare function _getRoutes(): ReadonlyArray<{
66
- pattern: string;
67
- hasGuard: boolean;
68
- }>;
69
- /** @internal Reset router state (for tests only). */
70
- export declare function _resetRouter(): void;
71
- export {};
72
- //# sourceMappingURL=router.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/router/router.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACjD,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC;AAC5D,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,GAAG,MAAM,CAAC;AAEhD,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC;CACvB;AAUD,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;CAC3B;AAED,MAAM,MAAM,WAAW,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AACrG,KAAK,cAAc,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;AAiBnD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,YAAY,GAAG,WAAW,GAAG,IAAI,CA2BxF;AAED;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAkBzE;AAiFD,eAAO,MAAM,MAAM;kBACH,YAAY,GAAG,IAAI;cAsCvB,QAAQ,MAAM,cAAc,GAAG,MAAM,IAAI;CAOpD,CAAC;AAEF,2EAA2E;AAC3E,wBAAgB,UAAU,IAAI,aAAa,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC,CAElF;AAID,qDAAqD;AACrD,wBAAgB,YAAY,IAAI,IAAI,CASnC"}
@@ -1,6 +0,0 @@
1
- /**
2
- * tina4js/ws — Signal-driven WebSocket client with auto-reconnect.
3
- */
4
- export { ws } from './ws';
5
- export type { SocketStatus, SocketOptions, ManagedSocket } from './ws';
6
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ws/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAC1B,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC"}
package/dist/ws/ws.d.ts DELETED
@@ -1,62 +0,0 @@
1
- /**
2
- * Tina4 WebSocket — Signal-driven WebSocket client with auto-reconnect.
3
- *
4
- * ws.connect(url, options?) — create a managed WebSocket connection
5
- * socket.status — reactive signal: 'connecting' | 'open' | 'closed' | 'reconnecting'
6
- * socket.connected — reactive signal: boolean
7
- * socket.lastMessage — reactive signal: last parsed message
8
- * socket.send(data) — send data (auto-stringify objects)
9
- * socket.on(event, handler) — listen for messages/open/close/error
10
- * socket.pipe(signal, reducer) — pipe messages directly into a signal
11
- * socket.close() — disconnect (stops reconnect)
12
- */
13
- import type { Signal } from '../core/signal';
14
- export type SocketStatus = 'connecting' | 'open' | 'closed' | 'reconnecting';
15
- export interface SocketOptions {
16
- /** Enable auto-reconnect on disconnect (default: true). */
17
- reconnect?: boolean;
18
- /** Initial reconnect delay in ms (default: 1000). */
19
- reconnectDelay?: number;
20
- /** Max reconnect delay in ms, for exponential backoff (default: 30000). */
21
- reconnectMaxDelay?: number;
22
- /** Max reconnect attempts before giving up (default: Infinity). */
23
- reconnectAttempts?: number;
24
- /** WebSocket sub-protocols. */
25
- protocols?: string | string[];
26
- }
27
- export type MessageHandler = (data: unknown) => void;
28
- export type OpenHandler = () => void;
29
- export type CloseHandler = (code: number, reason: string) => void;
30
- export type ErrorHandler = (error: Event) => void;
31
- type EventMap = {
32
- message: MessageHandler;
33
- open: OpenHandler;
34
- close: CloseHandler;
35
- error: ErrorHandler;
36
- };
37
- export interface ManagedSocket {
38
- /** Reactive connection status. */
39
- readonly status: Signal<SocketStatus>;
40
- /** Reactive boolean — true when status is 'open'. */
41
- readonly connected: Signal<boolean>;
42
- /** Reactive — last received message (parsed JSON or raw string). */
43
- readonly lastMessage: Signal<unknown>;
44
- /** Reactive — last error event, or null. */
45
- readonly error: Signal<Event | null>;
46
- /** Number of reconnect attempts so far. */
47
- readonly reconnectCount: Signal<number>;
48
- /** Send data. Objects are JSON.stringify'd automatically. */
49
- send(data: unknown): void;
50
- /** Listen for events. Returns unsubscribe function. */
51
- on<K extends keyof EventMap>(event: K, handler: EventMap[K]): () => void;
52
- /** Pipe messages into a signal via a reducer. */
53
- pipe<T>(target: Signal<T>, reducer: (message: unknown, current: T) => T): () => void;
54
- /** Close the connection and stop reconnecting. */
55
- close(code?: number, reason?: string): void;
56
- }
57
- declare function createSocket(url: string, options?: SocketOptions): ManagedSocket;
58
- export declare const ws: {
59
- connect: typeof createSocket;
60
- };
61
- export {};
62
- //# sourceMappingURL=ws.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ws.d.ts","sourceRoot":"","sources":["../../src/ws/ws.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAI7C,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,cAAc,CAAC;AAE7E,MAAM,WAAW,aAAa;IAC5B,2DAA2D;IAC3D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,qDAAqD;IACrD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,2EAA2E;IAC3E,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mEAAmE;IACnE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC/B;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;AACrD,MAAM,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;AACrC,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;AAClE,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;AAElD,KAAK,QAAQ,GAAG;IACd,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,YAAY,CAAC;IACpB,KAAK,EAAE,YAAY,CAAC;CACrB,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;IACtC,qDAAqD;IACrD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACpC,oEAAoE;IACpE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACtC,4CAA4C;IAC5C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IACrC,2CAA2C;IAC3C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAExC,6DAA6D;IAC7D,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAE1B,uDAAuD;IACvD,EAAE,CAAC,CAAC,SAAS,MAAM,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC;IAEzE,iDAAiD;IACjD,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;IAErF,kDAAkD;IAClD,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7C;AAcD,iBAAS,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,aAAa,CA0I7E;AAID,eAAO,MAAM,EAAE;;CAEd,CAAC"}