@tinyfx/runtime 0.1.2 → 0.1.4

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/README.md CHANGED
@@ -9,6 +9,7 @@ A lightweight collection of helpers for reactivity, DOM manipulation, and typed
9
9
  - **Signals** — Explicit reactivity without Proxies.
10
10
  - **DOM Helpers** — One-way bindings for text, attributes, and classes.
11
11
  - **Typed HTTP** — Minimal wrapper over `fetch` with response typing.
12
+ - **DI Container** — Simple `provide()`/`inject()` registry for app services.
12
13
  - **Tiny** — No dependencies, tree-shakeable, and extremely fast.
13
14
 
14
15
  ## Installation
@@ -76,6 +77,82 @@ const users = await api.get<User[]>("/users");
76
77
  await api.post("/users", { name: "Alice" });
77
78
  ```
78
79
 
80
+ ### DI Container (provide / inject)
81
+
82
+ TinyFX includes a small dependency injection container to avoid importing singleton instances everywhere.
83
+
84
+ Import it from `@tinyfx/runtime/di`:
85
+
86
+ ```ts
87
+ import { Container } from "@tinyfx/runtime/di";
88
+
89
+ class Config {
90
+ constructor(public baseUrl: string) {}
91
+ }
92
+
93
+ const container = new Container();
94
+ container.provide(Config, new Config("/api"));
95
+
96
+ const cfg = container.inject(Config);
97
+ console.log(cfg.baseUrl);
98
+ ```
99
+
100
+ #### Using DI with tinyfx components
101
+
102
+ When you use the tinyfx compiler, the generated glue calls your component behavior as:
103
+
104
+ ```ts
105
+ init(el, { container })
106
+ ```
107
+
108
+ So your component can inject services without importing global singletons:
109
+
110
+ ```ts
111
+ import type { TinyFxContext } from "@tinyfx/runtime/di";
112
+ import { HttpService } from "../lib/http.service";
113
+
114
+ export function init(el: HTMLElement, ctx: TinyFxContext) {
115
+ const http = ctx.container.inject(HttpService);
116
+ http.getWeather().then((text) => {
117
+ el.textContent = text;
118
+ });
119
+ }
120
+ ```
121
+
122
+ #### Example: service that uses the HTTP helper
123
+
124
+ ```ts
125
+ // src/lib/http.service.ts
126
+ import { createHttp } from "@tinyfx/runtime";
127
+
128
+ export class HttpService {
129
+ private readonly http;
130
+
131
+ constructor(baseUrl: string) {
132
+ this.http = createHttp({ baseUrl });
133
+ }
134
+
135
+ getWeather() {
136
+ // wttr.in can return plain text; your wrapper returns text when not JSON.
137
+ return this.http.get<string>("");
138
+ }
139
+ }
140
+ ```
141
+
142
+ ```ts
143
+ // src/main.ts
144
+ import { Container } from "@tinyfx/runtime/di";
145
+ import { setupComponents } from "./tinyfx.gen";
146
+ import { HttpService } from "./lib/http.service";
147
+
148
+ const container = new Container();
149
+ container.provide(HttpService, new HttpService("https://wttr.in/tunisa"));
150
+
151
+ document.addEventListener("DOMContentLoaded", () => {
152
+ setupComponents(container);
153
+ });
154
+ ```
155
+
79
156
  ## API Overview
80
157
 
81
158
  ### Signals
@@ -94,6 +171,13 @@ await api.post("/users", { name: "Alice" });
94
171
  - `client.put<T>(url: string, data?: any): Promise<T>`
95
172
  - `client.del<T>(url: string): Promise<T>`
96
173
 
174
+ ### DI
175
+ - `new Container()`
176
+ - `container.provide(token, instance)`
177
+ - `container.inject(token)`
178
+ - `createToken<T>(description: string): symbol`
179
+ - `TinyFxContext` (passed to component init via tinyfx glue)
180
+
97
181
  ## License
98
182
 
99
183
  MIT
@@ -1,2 +1,2 @@
1
- declare function buildUrl(url: string, base: string, params?: Record<string, string | number | boolean>): string;
2
- declare function sleep(ms: number): Promise<void>;
1
+ export declare function buildUrl(url: string, base: string, params?: Record<string, string | number | boolean>): string;
2
+ export declare function sleep(ms: number): Promise<void>;
@@ -1,5 +1,4 @@
1
- "use strict";
2
- function buildUrl(url, base, params) {
1
+ export function buildUrl(url, base, params) {
3
2
  const fullUrl = base + url;
4
3
  if (!params || Object.keys(params).length === 0)
5
4
  return fullUrl;
@@ -9,6 +8,6 @@ function buildUrl(url, base, params) {
9
8
  });
10
9
  return urlObj.toString().replace(urlObj.origin, '');
11
10
  }
12
- async function sleep(ms) {
11
+ export async function sleep(ms) {
13
12
  return new Promise(resolve => setTimeout(resolve, ms));
14
13
  }
package/dist/http/http.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // @tinyfx/runtime — HTTP client
2
2
  // Thin, typed wrapper over fetch.
3
3
  import { HttpError, HttpParseError, HttpTimeoutError } from "./data";
4
+ import { buildUrl, sleep } from "./helper";
4
5
  export function createHttp(config = {}) {
5
6
  var _a, _b, _c, _d, _e, _f, _g;
6
7
  const base = (_a = config.baseUrl) !== null && _a !== void 0 ? _a : "";
@@ -51,7 +52,7 @@ export function createHttp(config = {}) {
51
52
  fetchOptions.signal = combinedSignal;
52
53
  let res;
53
54
  try {
54
- res = await fetch(base + requestUrl, fetchOptions);
55
+ res = await fetch(requestUrl, fetchOptions);
55
56
  }
56
57
  catch (err) {
57
58
  clearTimeout(timeoutId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinyfx/runtime",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Minimal frontend runtime — signals, DOM helpers, typed HTTP, DTO mapping",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",