tina4js 1.0.15 → 1.1.1
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/api/fetch.d.ts +151 -0
- package/dist/api/fetch.d.ts.map +1 -0
- package/dist/api/index.d.ts +6 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api.cjs.js +1 -1
- package/dist/api.es.js +77 -52
- package/dist/core/component.d.ts +59 -0
- package/dist/core/component.d.ts.map +1 -0
- package/dist/core/html.d.ts +37 -0
- package/dist/core/html.d.ts.map +1 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/signal.d.ts +101 -0
- package/dist/core/signal.d.ts.map +1 -0
- package/dist/debug/index.d.ts +17 -0
- package/dist/debug/index.d.ts.map +1 -0
- package/dist/debug/overlay.d.ts +25 -0
- package/dist/debug/overlay.d.ts.map +1 -0
- package/dist/debug/panels/api.d.ts +5 -0
- package/dist/debug/panels/api.d.ts.map +1 -0
- package/dist/debug/panels/components.d.ts +5 -0
- package/dist/debug/panels/components.d.ts.map +1 -0
- package/dist/debug/panels/routes.d.ts +5 -0
- package/dist/debug/panels/routes.d.ts.map +1 -0
- package/dist/debug/panels/signals.d.ts +5 -0
- package/dist/debug/panels/signals.d.ts.map +1 -0
- package/dist/debug/styles.d.ts +5 -0
- package/dist/debug/styles.d.ts.map +1 -0
- package/dist/debug/trackers.d.ts +89 -0
- package/dist/debug/trackers.d.ts.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/pwa/index.d.ts +6 -0
- package/dist/pwa/index.d.ts.map +1 -0
- package/dist/pwa/pwa.d.ts +24 -0
- package/dist/pwa/pwa.d.ts.map +1 -0
- package/dist/router/index.d.ts +6 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/router/router.d.ts +72 -0
- package/dist/router/router.d.ts.map +1 -0
- package/dist/sse/index.d.ts +6 -0
- package/dist/sse/index.d.ts.map +1 -0
- package/dist/sse/sse.d.ts +72 -0
- package/dist/sse/sse.d.ts.map +1 -0
- package/dist/sse.cjs.js +2 -0
- package/dist/sse.es.js +137 -0
- package/dist/tina4.cjs.js +1 -1
- package/dist/tina4.es.js +6 -4
- package/dist/tina4js.min.js +48 -0
- package/dist/ws/index.d.ts +6 -0
- package/dist/ws/index.d.ts.map +1 -0
- package/dist/ws/ws.d.ts +62 -0
- package/dist/ws/ws.d.ts.map +1 -0
- package/package.json +5 -1
|
@@ -0,0 +1,151 @@
|
|
|
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
|
+
* Execute a GraphQL query or mutation.
|
|
89
|
+
*
|
|
90
|
+
* Sends a POST request with `{ query, variables }` body to the given path.
|
|
91
|
+
* Returns `{ data, errors }` — throws if the HTTP request itself fails.
|
|
92
|
+
*
|
|
93
|
+
* @param path - GraphQL endpoint path (e.g. `/api/graphql`).
|
|
94
|
+
* @param query - GraphQL query or mutation string.
|
|
95
|
+
* @param variables - Optional variables object.
|
|
96
|
+
* @param options - `{ params, headers }`.
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* const { data, errors } = await api.graphql('/api/graphql',
|
|
100
|
+
* '{ products(limit: 10) { id name price } }'
|
|
101
|
+
* );
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* const { data } = await api.graphql('/api/graphql',
|
|
105
|
+
* 'query ($term: String!) { search_products(term: $term) { id name } }',
|
|
106
|
+
* { term: "widget" }
|
|
107
|
+
* );
|
|
108
|
+
*/
|
|
109
|
+
graphql<T = unknown>(path: string, query: string, variables?: Record<string, unknown>, options?: RequestOptions): Promise<{
|
|
110
|
+
data: T | null;
|
|
111
|
+
errors?: Array<{
|
|
112
|
+
message: string;
|
|
113
|
+
}>;
|
|
114
|
+
}>;
|
|
115
|
+
/**
|
|
116
|
+
* Upload files via FormData (multipart/form-data).
|
|
117
|
+
*
|
|
118
|
+
* Unlike `post()`, this does NOT JSON-stringify the body or set
|
|
119
|
+
* Content-Type — the browser sets the multipart boundary automatically.
|
|
120
|
+
* Auth uses the Bearer token header (formToken cannot be injected into FormData).
|
|
121
|
+
*
|
|
122
|
+
* @param path - API path relative to `baseUrl`.
|
|
123
|
+
* @param formData - A FormData instance containing files and fields.
|
|
124
|
+
* @param options - `{ params, headers }` — query string params and per-request headers.
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* const form = new FormData();
|
|
128
|
+
* form.append('avatar', fileInput.files[0]);
|
|
129
|
+
* form.append('name', 'Alice');
|
|
130
|
+
* const result = await api.upload('/users/avatar', form);
|
|
131
|
+
*/
|
|
132
|
+
upload<T = unknown>(path: string, formData: FormData, options?: RequestOptions): Promise<T>;
|
|
133
|
+
/**
|
|
134
|
+
* Register a request or response interceptor.
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* // Add a custom header to every request
|
|
138
|
+
* api.intercept('request', (config) => {
|
|
139
|
+
* config.headers['X-Client'] = 'my-app';
|
|
140
|
+
* });
|
|
141
|
+
*
|
|
142
|
+
* // Redirect to login on 401
|
|
143
|
+
* api.intercept('response', (res) => {
|
|
144
|
+
* if (res.status === 401) navigate('/login');
|
|
145
|
+
* });
|
|
146
|
+
*/
|
|
147
|
+
intercept(type: "request" | "response", fn: RequestInterceptor | ResponseInterceptor): void;
|
|
148
|
+
/** @internal Reset state (for tests). */
|
|
149
|
+
_reset(): void;
|
|
150
|
+
};
|
|
151
|
+
//# sourceMappingURL=fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
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;;;;;;;;;;;;;;;;;;;;;OAqBG;YACW,CAAC,kBAAkB,MAAM,SAAS,MAAM,cAAc,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,cAAc,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;QAAC,MAAM,CAAC,EAAE,KAAK,CAAC;YAAE,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;IAIxL;;;;;;;;;;;;;;;;OAgBG;WACU,CAAC,kBAAkB,MAAM,YAAY,QAAQ,YAAY,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAiFjG;;;;;;;;;;;;;OAaG;oBACa,SAAS,GAAG,UAAU,MAAM,kBAAkB,GAAG,mBAAmB,GAAG,IAAI;IAQ3F,yCAAyC;cAC/B,IAAI;CAQf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
package/dist/api.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
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
|
|
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 q(e){try{localStorage.setItem(a.tokenKey,e)}catch{}}async function i(e,s,t,r){let c={method:e,headers:{"Content-Type":"application/json",...a.headers}};if(a.auth){const n=y();n&&(c.headers.Authorization=`Bearer ${n}`)}if(t!==void 0&&e!=="GET"){let n=typeof t=="object"&&t!==null?{...t}:t;if(a.auth&&typeof n=="object"&&n!==null){const u=y();u&&(n.formToken=u)}c.body=JSON.stringify(n)}if(r!=null&&r.headers&&Object.assign(c.headers,r.headers),r!=null&&r.params){const n=Object.entries(r.params).map(([u,I])=>`${encodeURIComponent(u)}=${encodeURIComponent(String(I))}`).join("&");s+=(s.includes("?")?"&":"?")+n}const d=a.baseUrl+s;c._url=d,c._requestId=++j;for(const n of k){const u=n(c);u&&(c=u)}const l=await fetch(d,c),g=l.headers.get("FreshToken");g&&q(g);const h=l.headers.get("Content-Type")??"";let f;h.includes("json")?f=await l.json():f=await l.text();let o={status:l.status,data:f,ok:l.ok,headers:l.headers,_requestId:c._requestId};for(const n of T){const u=n(o);u&&(o=u)}if(!l.ok)throw o;return o.data}const m={configure(e){Object.assign(a,e)},get(e,s){return i("GET",e,void 0,s)},post(e,s,t){return i("POST",e,s,t)},put(e,s,t){return i("PUT",e,s,t)},patch(e,s,t){return i("PATCH",e,s,t)},delete(e,s){return i("DELETE",e,void 0,s)},async graphql(e,s,t,r){return i("POST",e,{query:s,variables:t||{}},r)},async upload(e,s,t){let r={method:"POST",headers:{...a.headers},body:s};if(delete r.headers["Content-Type"],delete r.headers["content-type"],a.auth){const o=y();o&&(r.headers.Authorization=`Bearer ${o}`)}if(t!=null&&t.headers&&Object.assign(r.headers,t.headers),t!=null&&t.params){const o=Object.entries(t.params).map(([n,u])=>`${encodeURIComponent(n)}=${encodeURIComponent(String(u))}`).join("&");e+=(e.includes("?")?"&":"?")+o}const c=a.baseUrl+e;r._url=c,r._requestId=++j;for(const o of k){const n=o(r);n&&(r=n)}const d=await fetch(c,r),l=d.headers.get("FreshToken");l&&q(l);const g=d.headers.get("Content-Type")??"";let h;g.includes("json")?h=await d.json():h=await d.text();let f={status:d.status,data:h,ok:d.ok,headers:d.headers,_requestId:r._requestId};for(const o of T){const n=o(f);n&&(f=n)}if(!d.ok)throw f;return f.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=m;
|
package/dist/api.es.js
CHANGED
|
@@ -3,8 +3,8 @@ const a = {
|
|
|
3
3
|
auth: !1,
|
|
4
4
|
tokenKey: "tina4_token",
|
|
5
5
|
headers: {}
|
|
6
|
-
},
|
|
7
|
-
let
|
|
6
|
+
}, k = [], T = [];
|
|
7
|
+
let q = 0;
|
|
8
8
|
function y() {
|
|
9
9
|
try {
|
|
10
10
|
return localStorage.getItem(a.tokenKey);
|
|
@@ -12,13 +12,13 @@ function y() {
|
|
|
12
12
|
return null;
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
-
function
|
|
15
|
+
function I(e) {
|
|
16
16
|
try {
|
|
17
17
|
localStorage.setItem(a.tokenKey, e);
|
|
18
18
|
} catch {
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
async function
|
|
21
|
+
async function i(e, s, t, r) {
|
|
22
22
|
let c = {
|
|
23
23
|
method: e,
|
|
24
24
|
headers: {
|
|
@@ -27,32 +27,32 @@ async function h(e, s, r, n) {
|
|
|
27
27
|
}
|
|
28
28
|
};
|
|
29
29
|
if (a.auth) {
|
|
30
|
-
const
|
|
31
|
-
|
|
30
|
+
const n = y();
|
|
31
|
+
n && (c.headers.Authorization = `Bearer ${n}`);
|
|
32
32
|
}
|
|
33
|
-
if (
|
|
34
|
-
let
|
|
35
|
-
if (a.auth && typeof
|
|
33
|
+
if (t !== void 0 && e !== "GET") {
|
|
34
|
+
let n = typeof t == "object" && t !== null ? { ...t } : t;
|
|
35
|
+
if (a.auth && typeof n == "object" && n !== null) {
|
|
36
36
|
const u = y();
|
|
37
|
-
u && (
|
|
37
|
+
u && (n.formToken = u);
|
|
38
38
|
}
|
|
39
|
-
c.body = JSON.stringify(
|
|
39
|
+
c.body = JSON.stringify(n);
|
|
40
40
|
}
|
|
41
|
-
if (
|
|
42
|
-
const
|
|
43
|
-
s += (s.includes("?") ? "&" : "?") +
|
|
41
|
+
if (r != null && r.headers && Object.assign(c.headers, r.headers), r != null && r.params) {
|
|
42
|
+
const n = Object.entries(r.params).map(([u, j]) => `${encodeURIComponent(u)}=${encodeURIComponent(String(j))}`).join("&");
|
|
43
|
+
s += (s.includes("?") ? "&" : "?") + n;
|
|
44
44
|
}
|
|
45
45
|
const d = a.baseUrl + s;
|
|
46
|
-
c._url = d, c._requestId = ++
|
|
47
|
-
for (const
|
|
48
|
-
const u =
|
|
46
|
+
c._url = d, c._requestId = ++q;
|
|
47
|
+
for (const n of k) {
|
|
48
|
+
const u = n(c);
|
|
49
49
|
u && (c = u);
|
|
50
50
|
}
|
|
51
|
-
const f = await fetch(d, c),
|
|
52
|
-
|
|
53
|
-
const
|
|
51
|
+
const f = await fetch(d, c), g = f.headers.get("FreshToken");
|
|
52
|
+
g && I(g);
|
|
53
|
+
const h = f.headers.get("Content-Type") ?? "";
|
|
54
54
|
let l;
|
|
55
|
-
|
|
55
|
+
h.includes("json") ? l = await f.json() : l = await f.text();
|
|
56
56
|
let o = {
|
|
57
57
|
status: f.status,
|
|
58
58
|
data: l,
|
|
@@ -60,8 +60,8 @@ async function h(e, s, r, n) {
|
|
|
60
60
|
headers: f.headers,
|
|
61
61
|
_requestId: c._requestId
|
|
62
62
|
};
|
|
63
|
-
for (const
|
|
64
|
-
const u =
|
|
63
|
+
for (const n of T) {
|
|
64
|
+
const u = n(o);
|
|
65
65
|
u && (o = u);
|
|
66
66
|
}
|
|
67
67
|
if (!f.ok)
|
|
@@ -91,7 +91,7 @@ const m = {
|
|
|
91
91
|
* const data = await api.get('/products', { params: { page: 2, limit: 20 } });
|
|
92
92
|
*/
|
|
93
93
|
get(e, s) {
|
|
94
|
-
return
|
|
94
|
+
return i("GET", e, void 0, s);
|
|
95
95
|
},
|
|
96
96
|
/**
|
|
97
97
|
* HTTP POST request.
|
|
@@ -101,20 +101,45 @@ const m = {
|
|
|
101
101
|
* @example
|
|
102
102
|
* await api.post('/users', { name: 'Alice', role: 'admin' });
|
|
103
103
|
*/
|
|
104
|
-
post(e, s,
|
|
105
|
-
return
|
|
104
|
+
post(e, s, t) {
|
|
105
|
+
return i("POST", e, s, t);
|
|
106
106
|
},
|
|
107
107
|
/** HTTP PUT — full replace. */
|
|
108
|
-
put(e, s,
|
|
109
|
-
return
|
|
108
|
+
put(e, s, t) {
|
|
109
|
+
return i("PUT", e, s, t);
|
|
110
110
|
},
|
|
111
111
|
/** HTTP PATCH — partial update. */
|
|
112
|
-
patch(e, s,
|
|
113
|
-
return
|
|
112
|
+
patch(e, s, t) {
|
|
113
|
+
return i("PATCH", e, s, t);
|
|
114
114
|
},
|
|
115
115
|
/** HTTP DELETE. */
|
|
116
116
|
delete(e, s) {
|
|
117
|
-
return
|
|
117
|
+
return i("DELETE", e, void 0, s);
|
|
118
|
+
},
|
|
119
|
+
/**
|
|
120
|
+
* Execute a GraphQL query or mutation.
|
|
121
|
+
*
|
|
122
|
+
* Sends a POST request with `{ query, variables }` body to the given path.
|
|
123
|
+
* Returns `{ data, errors }` — throws if the HTTP request itself fails.
|
|
124
|
+
*
|
|
125
|
+
* @param path - GraphQL endpoint path (e.g. `/api/graphql`).
|
|
126
|
+
* @param query - GraphQL query or mutation string.
|
|
127
|
+
* @param variables - Optional variables object.
|
|
128
|
+
* @param options - `{ params, headers }`.
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* const { data, errors } = await api.graphql('/api/graphql',
|
|
132
|
+
* '{ products(limit: 10) { id name price } }'
|
|
133
|
+
* );
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* const { data } = await api.graphql('/api/graphql',
|
|
137
|
+
* 'query ($term: String!) { search_products(term: $term) { id name } }',
|
|
138
|
+
* { term: "widget" }
|
|
139
|
+
* );
|
|
140
|
+
*/
|
|
141
|
+
async graphql(e, s, t, r) {
|
|
142
|
+
return i("POST", e, { query: s, variables: t || {} }, r);
|
|
118
143
|
},
|
|
119
144
|
/**
|
|
120
145
|
* Upload files via FormData (multipart/form-data).
|
|
@@ -133,8 +158,8 @@ const m = {
|
|
|
133
158
|
* form.append('name', 'Alice');
|
|
134
159
|
* const result = await api.upload('/users/avatar', form);
|
|
135
160
|
*/
|
|
136
|
-
async upload(e, s,
|
|
137
|
-
let
|
|
161
|
+
async upload(e, s, t) {
|
|
162
|
+
let r = {
|
|
138
163
|
method: "POST",
|
|
139
164
|
headers: {
|
|
140
165
|
...a.headers
|
|
@@ -142,35 +167,35 @@ const m = {
|
|
|
142
167
|
},
|
|
143
168
|
body: s
|
|
144
169
|
};
|
|
145
|
-
if (delete
|
|
170
|
+
if (delete r.headers["Content-Type"], delete r.headers["content-type"], a.auth) {
|
|
146
171
|
const o = y();
|
|
147
|
-
o && (
|
|
172
|
+
o && (r.headers.Authorization = `Bearer ${o}`);
|
|
148
173
|
}
|
|
149
|
-
if (
|
|
150
|
-
const o = Object.entries(
|
|
174
|
+
if (t != null && t.headers && Object.assign(r.headers, t.headers), t != null && t.params) {
|
|
175
|
+
const o = Object.entries(t.params).map(([n, u]) => `${encodeURIComponent(n)}=${encodeURIComponent(String(u))}`).join("&");
|
|
151
176
|
e += (e.includes("?") ? "&" : "?") + o;
|
|
152
177
|
}
|
|
153
178
|
const c = a.baseUrl + e;
|
|
154
|
-
|
|
155
|
-
for (const o of
|
|
156
|
-
const
|
|
157
|
-
|
|
179
|
+
r._url = c, r._requestId = ++q;
|
|
180
|
+
for (const o of k) {
|
|
181
|
+
const n = o(r);
|
|
182
|
+
n && (r = n);
|
|
158
183
|
}
|
|
159
|
-
const d = await fetch(c,
|
|
160
|
-
f &&
|
|
161
|
-
const
|
|
162
|
-
let
|
|
163
|
-
|
|
184
|
+
const d = await fetch(c, r), f = d.headers.get("FreshToken");
|
|
185
|
+
f && I(f);
|
|
186
|
+
const g = d.headers.get("Content-Type") ?? "";
|
|
187
|
+
let h;
|
|
188
|
+
g.includes("json") ? h = await d.json() : h = await d.text();
|
|
164
189
|
let l = {
|
|
165
190
|
status: d.status,
|
|
166
|
-
data:
|
|
191
|
+
data: h,
|
|
167
192
|
ok: d.ok,
|
|
168
193
|
headers: d.headers,
|
|
169
|
-
_requestId:
|
|
194
|
+
_requestId: r._requestId
|
|
170
195
|
};
|
|
171
196
|
for (const o of T) {
|
|
172
|
-
const
|
|
173
|
-
|
|
197
|
+
const n = o(l);
|
|
198
|
+
n && (l = n);
|
|
174
199
|
}
|
|
175
200
|
if (!d.ok)
|
|
176
201
|
throw l;
|
|
@@ -191,11 +216,11 @@ const m = {
|
|
|
191
216
|
* });
|
|
192
217
|
*/
|
|
193
218
|
intercept(e, s) {
|
|
194
|
-
e === "request" ?
|
|
219
|
+
e === "request" ? k.push(s) : T.push(s);
|
|
195
220
|
},
|
|
196
221
|
/** @internal Reset state (for tests). */
|
|
197
222
|
_reset() {
|
|
198
|
-
a.baseUrl = "", a.auth = !1, a.tokenKey = "tina4_token", a.headers = {},
|
|
223
|
+
a.baseUrl = "", a.auth = !1, a.tokenKey = "tina4_token", a.headers = {}, k.length = 0, T.length = 0;
|
|
199
224
|
}
|
|
200
225
|
};
|
|
201
226
|
export {
|
|
@@ -0,0 +1,59 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,101 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
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
|