@axman/remote 0.0.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/README.md ADDED
@@ -0,0 +1,78 @@
1
+ ## @axman/remote
2
+
3
+ Typed helpers for remote data state: discriminated `Remote<T>` union with `pending`, `error`, `success`, plus `match`, `all` and `map` utilities.
4
+
5
+ ### Install
6
+
7
+ ```bash
8
+ npm i @axman/remote
9
+ # or
10
+ pnpm add @axman/remote
11
+ # or
12
+ bun add @axman/remote
13
+ ```
14
+
15
+ ### Remote type
16
+
17
+ `Remote<T>` is a discriminated union with `status` ∈ `"pending" | "error" | "success"` and convenient flags `isPending/isError/isSuccess`.
18
+
19
+ ```ts
20
+ import { type Remote, error, pending, success } from "@axman/remote";
21
+
22
+ const a: Remote<number> = pending();
23
+ const b: Remote<number> = error(new Error("boom"));
24
+ const c: Remote<number> = success(42);
25
+ ```
26
+
27
+ ### match(remote, cases)
28
+
29
+ Pattern-match on `Remote<T>` in a type-safe way.
30
+
31
+ ```ts
32
+ import { error, match, pending, success } from "@axman/remote";
33
+
34
+ const out = match(success({ id: 1 }), {
35
+ pending: () => "loading",
36
+ error: (e) => `error: ${e.message}`,
37
+ success: (data) => `ok: ${data.id}`,
38
+ });
39
+ // => 'ok: 1'
40
+ ```
41
+
42
+ ### all(...remotes)
43
+
44
+ Combine multiple `Remote`s into one. Precedence: any `error` → `error`; else if any `pending` → `pending`; otherwise `success` with a tuple of data.
45
+
46
+ ```ts
47
+ import { all, error, pending, success } from "@axman/remote";
48
+
49
+ all(error(new Error("x")), pending(), success(1));
50
+ // => { status: 'error', ... }
51
+
52
+ all(pending(), success(1));
53
+ // => { status: 'pending', ... }
54
+
55
+ const r = all(success(1), success("x" as const));
56
+ // r.data has type [number, 'x']
57
+ ```
58
+
59
+ ### map(remote, fn)
60
+
61
+ Map data of a successful `Remote<T>` to `Remote<R>`; passes through `pending` and `error` unchanged.
62
+
63
+ ```ts
64
+ import { type Remote, error, map, pending, success } from "@axman/remote";
65
+
66
+ map(success(2), (n) => n * 10);
67
+ // => { status: 'success', data: 20, ... }
68
+
69
+ map(pending() as Remote<number>, (n) => n * 10);
70
+ // => { status: 'pending', ... }
71
+
72
+ map(error(new Error("x")) as Remote<number>, (n) => n * 10);
73
+ // => { status: 'error', ... }
74
+ ```
75
+
76
+ ### License
77
+
78
+ MIT
package/dist/all.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { Remote } from './remote';
2
+ type RemoteDataList<RemoteList extends readonly Remote<unknown>[]> = {
3
+ [K in keyof RemoteList]: RemoteList[K] extends Remote<infer D> ? D : never;
4
+ };
5
+ export declare function all<RemoteList extends readonly Remote<unknown>[]>(...values: RemoteList): Remote<RemoteDataList<RemoteList>>;
6
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function t(){return{status:"pending",isPending:!0,isError:!1,isSuccess:!1,error:void 0,data:void 0}}function i(r){return{status:"error",isPending:!1,isError:!0,isSuccess:!1,error:r,data:null}}function u(r){return{status:"success",isPending:!1,isError:!1,isSuccess:!0,error:null,data:r}}function c(...r){let e=!1;for(const n of r){if(n.isError)return i(n.error);n.isPending&&(e=!0)}if(e)return t();const s=r.map(n=>n.data);return u(s)}function o(r,e){switch(r.status){case"pending":return e.pending();case"error":return e.error(r.error);case"success":return e.success(r.data)}}function a(r,e){return o(r,{pending:()=>t(),error:s=>i(s),success:s=>u(e(s))})}const d=Object.freeze(Object.defineProperty({__proto__:null,all:c,error:i,map:a,match:o,pending:t,success:u},Symbol.toStringTag,{value:"Module"}));exports.all=c;exports.error=i;exports.map=a;exports.match=o;exports.pending=t;exports.remote=d;exports.success=u;
@@ -0,0 +1,2 @@
1
+ export * from './index.exports';
2
+ export * as remote from './index.exports';
@@ -0,0 +1,77 @@
1
+ function t() {
2
+ return {
3
+ status: "pending",
4
+ isPending: !0,
5
+ isError: !1,
6
+ isSuccess: !1,
7
+ error: void 0,
8
+ data: void 0
9
+ };
10
+ }
11
+ function i(r) {
12
+ return {
13
+ status: "error",
14
+ isPending: !1,
15
+ isError: !0,
16
+ isSuccess: !1,
17
+ error: r,
18
+ data: null
19
+ };
20
+ }
21
+ function u(r) {
22
+ return {
23
+ status: "success",
24
+ isPending: !1,
25
+ isError: !1,
26
+ isSuccess: !0,
27
+ error: null,
28
+ data: r
29
+ };
30
+ }
31
+ function c(...r) {
32
+ let e = !1;
33
+ for (const n of r) {
34
+ if (n.isError)
35
+ return i(n.error);
36
+ n.isPending && (e = !0);
37
+ }
38
+ if (e)
39
+ return t();
40
+ const s = r.map((n) => n.data);
41
+ return u(s);
42
+ }
43
+ function o(r, e) {
44
+ switch (r.status) {
45
+ case "pending":
46
+ return e.pending();
47
+ case "error":
48
+ return e.error(r.error);
49
+ case "success":
50
+ return e.success(r.data);
51
+ }
52
+ }
53
+ function a(r, e) {
54
+ return o(r, {
55
+ pending: () => t(),
56
+ error: (s) => i(s),
57
+ success: (s) => u(e(s))
58
+ });
59
+ }
60
+ const d = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
61
+ __proto__: null,
62
+ all: c,
63
+ error: i,
64
+ map: a,
65
+ match: o,
66
+ pending: t,
67
+ success: u
68
+ }, Symbol.toStringTag, { value: "Module" }));
69
+ export {
70
+ c as all,
71
+ i as error,
72
+ a as map,
73
+ o as match,
74
+ t as pending,
75
+ d as remote,
76
+ u as success
77
+ };
@@ -0,0 +1,4 @@
1
+ export * from './all';
2
+ export * from './map';
3
+ export * from './match';
4
+ export * from './remote';
package/dist/map.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import { Remote } from './remote';
2
+ export declare function map<T, R>(remote: Remote<T>, fn: (data: T) => R): Remote<R>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ import { Remote } from './remote';
2
+ export type MatchCases<T, R> = {
3
+ pending: () => R;
4
+ error: (error: Error) => R;
5
+ success: (data: T) => R;
6
+ };
7
+ export declare function match<T, R>(remote: Remote<T>, cases: MatchCases<T, R>): R;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,25 @@
1
+ export type Remote<T> = {
2
+ status: 'pending';
3
+ isPending: true;
4
+ isError: false;
5
+ isSuccess: false;
6
+ error: undefined;
7
+ data: undefined;
8
+ } | {
9
+ status: 'error';
10
+ isPending: false;
11
+ isError: true;
12
+ isSuccess: false;
13
+ error: Error;
14
+ data: null;
15
+ } | {
16
+ status: 'success';
17
+ isPending: false;
18
+ isError: false;
19
+ isSuccess: true;
20
+ error: null;
21
+ data: T;
22
+ };
23
+ export declare function pending(): Remote<never>;
24
+ export declare function error(error: Error): Remote<never>;
25
+ export declare function success<T>(data: T): Remote<T>;
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@axman/remote",
3
+ "author": "akhmanov",
4
+ "version": "0.0.1",
5
+ "description": "Remote data helper types and utilities for TypeScript",
6
+ "license": "MIT",
7
+ "private": false,
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
+ "sideEffects": false,
12
+ "main": "./dist/index.cjs.js",
13
+ "module": "./dist/index.es.js",
14
+ "types": "./dist/index.d.ts",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/akhmanov/remote-js.git"
18
+ },
19
+ "exports": {
20
+ ".": {
21
+ "types": "./dist/index.d.ts",
22
+ "import": "./dist/index.es.js",
23
+ "require": "./dist/index.cjs.js",
24
+ "default": "./dist/index.es.js"
25
+ },
26
+ "./package.json": "./package.json"
27
+ },
28
+ "files": [
29
+ "dist"
30
+ ],
31
+ "keywords": [
32
+ "remote"
33
+ ],
34
+ "scripts": {
35
+ "build": "tsc -b && bunx --bun vite build -c vite.config.ts",
36
+ "fmt": "biome format --write .",
37
+ "lint": "biome check .",
38
+ "lint:fix": "biome check --fix ."
39
+ },
40
+ "devDependencies": {
41
+ "@tsconfig/strictest": "^2.0.8",
42
+ "@types/node": "^24.3.0",
43
+ "typescript": "^5.9.2",
44
+ "vite": "^7.1.4",
45
+ "vite-plugin-dts": "^4.5.4",
46
+ "vitest": "^3.2.4"
47
+ }
48
+ }