void-snippets-monorepo 0.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/README.md +2261 -0
- package/package.json +18 -0
- package/packages/client/package.json +47 -0
- package/packages/client/src/configure.ts +34 -0
- package/packages/client/src/index.ts +4 -0
- package/packages/client/src/services/base-api.service.ts +26 -0
- package/packages/client/src/services/resource-api.service.ts +117 -0
- package/packages/client/src/utils/handle-api-error.ts +20 -0
- package/packages/client/tsconfig.json +13 -0
- package/packages/client/tsup.config.ts +10 -0
- package/packages/core/package.json +41 -0
- package/packages/core/src/id.ts +19 -0
- package/packages/core/src/index.ts +4 -0
- package/packages/core/src/string-to-id.ts +22 -0
- package/packages/core/src/types/index.ts +86 -0
- package/packages/core/src/utils/catch-error.ts +20 -0
- package/packages/core/tsconfig.json +13 -0
- package/packages/core/tsup.config.ts +9 -0
- package/packages/react/package.json +80 -0
- package/packages/react/src/hooks/createResourceHooks.ts +872 -0
- package/packages/react/src/hooks/useAlertMessage.ts +45 -0
- package/packages/react/src/hooks/useAsyncState.ts +110 -0
- package/packages/react/src/hooks/useCallTimer.ts +37 -0
- package/packages/react/src/hooks/useModal.ts +71 -0
- package/packages/react/src/hooks/usePagination.ts +57 -0
- package/packages/react/src/index.ts +43 -0
- package/packages/react/src/routing/createRouteContract.ts +483 -0
- package/packages/react/src/socket/createSocketHooks.ts +351 -0
- package/packages/react/tsconfig.json +14 -0
- package/packages/react/tsup.config.ts +10 -0
- package/pnpm-workspace.yaml +2 -0
- package/tsconfig.base.json +12 -0
package/package.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "void-snippets-monorepo",
|
|
3
|
+
"private": false,
|
|
4
|
+
"version": "0.1.1",
|
|
5
|
+
"devDependencies": {
|
|
6
|
+
"typescript": "^5.4.0",
|
|
7
|
+
"tsup": "^8.0.0"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "pnpm -r run build",
|
|
11
|
+
"build:core": "pnpm --filter @void-snippets/core run build",
|
|
12
|
+
"build:client": "pnpm --filter @void-snippets/client run build",
|
|
13
|
+
"build:react": "pnpm --filter @void-snippets/react run build",
|
|
14
|
+
"dev": "pnpm -r run dev",
|
|
15
|
+
"publish:all": "pnpm -r publish --access public --no-git-checks",
|
|
16
|
+
"version:bump": "pnpm -r exec npm version"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@void-snippets/client",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Framework-agnostic HTTP resource service for TypeScript projects",
|
|
5
|
+
"homepage": "https://void-snippets.vercel.app",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/shahtirthhh/void-snippets.git",
|
|
9
|
+
"directory": "packages/client"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/shahtirthhh/void-snippets/issues"
|
|
13
|
+
},
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"module": "./dist/index.mjs",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"import": "./dist/index.mjs",
|
|
20
|
+
"require": "./dist/index.js",
|
|
21
|
+
"default": "./dist/index.mjs"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsup",
|
|
29
|
+
"dev": "tsup --watch"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"axios",
|
|
33
|
+
"typescript",
|
|
34
|
+
"api",
|
|
35
|
+
"void-snippets",
|
|
36
|
+
"resource"
|
|
37
|
+
],
|
|
38
|
+
"license": "MIT",
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@void-snippets/core": "workspace:*",
|
|
41
|
+
"axios": "^1.6.0"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"tsup": "^8.0.0",
|
|
45
|
+
"typescript": "^5.4.0"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { AxiosInstance } from "axios";
|
|
2
|
+
|
|
3
|
+
let _instance: AxiosInstance | null = null;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Registers your axios instance globally.
|
|
7
|
+
* Call this once at your app's entry point before using any service.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* import axios from 'axios';
|
|
11
|
+
* import { configure } from '@void-snippets/client';
|
|
12
|
+
*
|
|
13
|
+
* const axiosInstance = axios.create({ baseURL: 'https://api.example.com' });
|
|
14
|
+
* configure(axiosInstance);
|
|
15
|
+
*/
|
|
16
|
+
export function configure(instance: AxiosInstance): void {
|
|
17
|
+
_instance = instance;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @internal — used by BaseApiService, not part of the public API.
|
|
22
|
+
*/
|
|
23
|
+
export function getConfiguredInstance(): AxiosInstance {
|
|
24
|
+
if (!_instance) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
"[@void-snippets/client] No axios instance configured.\n" +
|
|
27
|
+
"Call configure(axiosInstance) once at your app entry point before using any resource service.\n\n" +
|
|
28
|
+
"Example:\n" +
|
|
29
|
+
" import { configure } from '@void-snippets/client';\n" +
|
|
30
|
+
" configure(myAxiosInstance);"
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
return _instance;
|
|
34
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { AxiosInstance } from "axios";
|
|
2
|
+
import { getConfiguredInstance } from "../configure";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Abstract base for all resource services.
|
|
6
|
+
* Automatically uses the axios instance registered via configure().
|
|
7
|
+
*/
|
|
8
|
+
export abstract class BaseApiService {
|
|
9
|
+
protected readonly endpoint: string;
|
|
10
|
+
|
|
11
|
+
constructor(endpoint: string) {
|
|
12
|
+
this.endpoint = endpoint;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Returns the globally configured axios instance.
|
|
17
|
+
* Lazy-evaluated so configure() can be called after class instantiation.
|
|
18
|
+
*/
|
|
19
|
+
protected get http(): AxiosInstance {
|
|
20
|
+
return getConfiguredInstance();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
protected getFullUrl(path: string): string {
|
|
24
|
+
return `${this.endpoint}${path}`;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
VSQueryParams,
|
|
3
|
+
VSDefaultPaginatedResponse,
|
|
4
|
+
VSDefaultSingleResponse,
|
|
5
|
+
} from "@void-snippets/core";
|
|
6
|
+
import { handleApiError } from "../utils/handle-api-error";
|
|
7
|
+
import { BaseApiService } from "./base-api.service";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Generic CRUD resource service. Extend this class for each API resource.
|
|
11
|
+
*
|
|
12
|
+
* @typeParam TId - The type of the resource's identifier (e.g., string)
|
|
13
|
+
* @typeParam TBase - The base entity type returned in list responses
|
|
14
|
+
* @typeParam TDetail - The detailed entity type returned in single-item responses (defaults to TBase)
|
|
15
|
+
* @typeParam TCreate - The payload type for create operations (defaults to Partial<TBase>)
|
|
16
|
+
* @typeParam TUpdate - The payload type for update operations (defaults to Partial<TBase>)
|
|
17
|
+
* @typeParam TListRaw - Raw API list response shape (defaults to VSDefaultPaginatedResponse<TBase>)
|
|
18
|
+
* @typeParam TSingleRaw - Raw API single-item response shape (defaults to VSDefaultSingleResponse<TDetail>)
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* import { ResourceService } from '@void-snippets/client';
|
|
22
|
+
* import type { Contact } from './contacts.types';
|
|
23
|
+
*
|
|
24
|
+
* export class ContactsApiService extends ResourceService<
|
|
25
|
+
* Contact.Id,
|
|
26
|
+
* Contact.Base,
|
|
27
|
+
* Contact.WithCreatedBy,
|
|
28
|
+
* Contact.Apis.CreatePayload,
|
|
29
|
+
* Contact.Apis.UpdatePayload
|
|
30
|
+
* > {
|
|
31
|
+
* constructor() {
|
|
32
|
+
* super('/contacts');
|
|
33
|
+
* }
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* export const ContactsApis = new ContactsApiService();
|
|
37
|
+
*/
|
|
38
|
+
export class ResourceService<
|
|
39
|
+
TId,
|
|
40
|
+
TBase,
|
|
41
|
+
TDetail = TBase,
|
|
42
|
+
TCreate = Partial<TBase>,
|
|
43
|
+
TUpdate = Partial<TBase>,
|
|
44
|
+
TListRaw = VSDefaultPaginatedResponse<TBase>,
|
|
45
|
+
TSingleRaw = VSDefaultSingleResponse<TDetail>,
|
|
46
|
+
> extends BaseApiService {
|
|
47
|
+
declare readonly __types: {
|
|
48
|
+
id: TId;
|
|
49
|
+
base: TBase;
|
|
50
|
+
detail: TDetail;
|
|
51
|
+
create: TCreate;
|
|
52
|
+
update: TUpdate;
|
|
53
|
+
listRaw: TListRaw;
|
|
54
|
+
singleRaw: TSingleRaw;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
constructor(endpoint: string) {
|
|
58
|
+
super(endpoint);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async list(params?: VSQueryParams): Promise<TListRaw> {
|
|
62
|
+
try {
|
|
63
|
+
const { data } = await this.http.get<TListRaw>(this.getFullUrl(""), {
|
|
64
|
+
params,
|
|
65
|
+
});
|
|
66
|
+
return data;
|
|
67
|
+
} catch (error) {
|
|
68
|
+
handleApiError(error);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async get(id: TId): Promise<TSingleRaw> {
|
|
73
|
+
try {
|
|
74
|
+
const { data } = await this.http.get<TSingleRaw>(
|
|
75
|
+
`${this.getFullUrl("")}/${String(id)}`
|
|
76
|
+
);
|
|
77
|
+
return data;
|
|
78
|
+
} catch (error) {
|
|
79
|
+
handleApiError(error);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async create(payload: TCreate): Promise<TSingleRaw> {
|
|
84
|
+
try {
|
|
85
|
+
const { data } = await this.http.post<TSingleRaw>(
|
|
86
|
+
this.getFullUrl(""),
|
|
87
|
+
payload
|
|
88
|
+
);
|
|
89
|
+
return data;
|
|
90
|
+
} catch (error) {
|
|
91
|
+
handleApiError(error);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async update(id: TId, payload: TUpdate): Promise<TSingleRaw> {
|
|
96
|
+
try {
|
|
97
|
+
const { data } = await this.http.patch<TSingleRaw>(
|
|
98
|
+
`${this.getFullUrl("")}/${String(id)}`,
|
|
99
|
+
payload
|
|
100
|
+
);
|
|
101
|
+
return data;
|
|
102
|
+
} catch (error) {
|
|
103
|
+
handleApiError(error);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async delete(id: TId): Promise<TSingleRaw> {
|
|
108
|
+
try {
|
|
109
|
+
const { data } = await this.http.delete<TSingleRaw>(
|
|
110
|
+
`${this.getFullUrl("")}/${String(id)}`
|
|
111
|
+
);
|
|
112
|
+
return data;
|
|
113
|
+
} catch (error) {
|
|
114
|
+
handleApiError(error);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { AxiosError } from "axios";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Normalizes axios and generic errors into a standard Error.
|
|
5
|
+
* Always throws — return type is `never`.
|
|
6
|
+
*/
|
|
7
|
+
export function handleApiError(error: unknown): never {
|
|
8
|
+
if (error instanceof AxiosError) {
|
|
9
|
+
const serverMessage =
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
11
|
+
(error.response?.data as { message?: string })?.message;
|
|
12
|
+
throw new Error(serverMessage ?? error.message);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (error instanceof Error) {
|
|
16
|
+
throw error;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
throw new Error("An unexpected error occurred.");
|
|
20
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@void-snippets/core",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Core types and utilities for void-snippets packages",
|
|
5
|
+
"homepage": "https://void-snippets.vercel.app",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/shahtirthhh/void-snippets.git",
|
|
9
|
+
"directory": "packages/core"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/shahtirthhh/void-snippets/issues"
|
|
13
|
+
},
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"module": "./dist/index.mjs",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"import": "./dist/index.mjs",
|
|
20
|
+
"require": "./dist/index.js",
|
|
21
|
+
"default": "./dist/index.mjs"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsup",
|
|
29
|
+
"dev": "tsup --watch"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"typescript",
|
|
33
|
+
"void-snippets",
|
|
34
|
+
"types"
|
|
35
|
+
],
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"tsup": "^8.0.0",
|
|
39
|
+
"typescript": "^5.4.0"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a branded (nominal) type from a primitive.
|
|
3
|
+
*
|
|
4
|
+
* Branded types prevent accidental mixing of structurally identical
|
|
5
|
+
* but semantically different IDs at compile time.
|
|
6
|
+
*
|
|
7
|
+
* @typeParam K - The underlying primitive type (usually `string`)
|
|
8
|
+
* @typeParam T - A unique brand tag per entity (use a string literal)
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* type ContactId = VSId<string, 'Contact'>;
|
|
12
|
+
* type UserId = VSId<string, 'User'>;
|
|
13
|
+
*
|
|
14
|
+
* declare const contactId: ContactId;
|
|
15
|
+
* declare let userId: UserId;
|
|
16
|
+
*
|
|
17
|
+
* userId = contactId; // ✅ TypeScript error — brands don't match
|
|
18
|
+
*/
|
|
19
|
+
export type VSId<K, T> = K & { __brand: T };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { VSId } from "./id";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Casts a plain `string` to a branded `VSId` type.
|
|
5
|
+
*
|
|
6
|
+
* Use at runtime boundaries (e.g. URL params, API responses, localStorage)
|
|
7
|
+
* where you receive a raw string and need the correct branded ID type.
|
|
8
|
+
*
|
|
9
|
+
* @typeParam T - Must be a `VSId<string, Brand>` type
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* import type { VSId } from '@void-snippets/core';
|
|
13
|
+
* import { stringToId } from '@void-snippets/core';
|
|
14
|
+
*
|
|
15
|
+
* type ContactId = VSId<string, 'Contact'>;
|
|
16
|
+
*
|
|
17
|
+
* const raw = params.contactId; // string
|
|
18
|
+
* const id = stringToId<ContactId>(raw); // ContactId ✅
|
|
19
|
+
*/
|
|
20
|
+
export const stringToId = <T extends VSId<string, unknown>>(
|
|
21
|
+
id: string
|
|
22
|
+
): T => id as unknown as T;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// PAGINATION
|
|
3
|
+
// ============================================================================
|
|
4
|
+
|
|
5
|
+
export interface VSPagination {
|
|
6
|
+
page: number;
|
|
7
|
+
limit: number;
|
|
8
|
+
totalPages: number;
|
|
9
|
+
totalDocuments: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface VSQueryParams {
|
|
13
|
+
page?: number;
|
|
14
|
+
limit?: number;
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// DEFAULT API RESPONSE SHAPES
|
|
20
|
+
// These are the shapes the library uses out-of-the-box.
|
|
21
|
+
// If your API returns a different shape, provide custom adapters.
|
|
22
|
+
// ============================================================================
|
|
23
|
+
|
|
24
|
+
export interface VSDefaultPaginatedData<T> {
|
|
25
|
+
items: T[];
|
|
26
|
+
page: number;
|
|
27
|
+
limit: number;
|
|
28
|
+
totalPages: number;
|
|
29
|
+
totalDocuments: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface VSDefaultPaginatedResponse<T> {
|
|
33
|
+
data: VSDefaultPaginatedData<T>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface VSDefaultSingleResponse<T> {
|
|
37
|
+
data: T;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// ============================================================================
|
|
41
|
+
// ADAPTER INTERFACES
|
|
42
|
+
// Adapters decouple the library from any specific API response shape.
|
|
43
|
+
// Pass them to createResourceHooks() if your API shape differs from defaults.
|
|
44
|
+
//
|
|
45
|
+
// @example
|
|
46
|
+
// const adapters: VSAdapters<MyListRes, User, MySingleRes, UserDetail> = {
|
|
47
|
+
// fromList: (raw) => ({ items: raw.results, pagination: { ... } }),
|
|
48
|
+
// fromSingle: (raw) => raw.payload,
|
|
49
|
+
// };
|
|
50
|
+
// ============================================================================
|
|
51
|
+
|
|
52
|
+
export interface VSListResult<TBase> {
|
|
53
|
+
items: TBase[];
|
|
54
|
+
pagination: VSPagination;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface VSAdapters<TListRaw, TBase, TSingleRaw, TDetail> {
|
|
58
|
+
fromList: (raw: TListRaw) => VSListResult<TBase>;
|
|
59
|
+
fromSingle: (raw: TSingleRaw) => TDetail;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ============================================================================
|
|
63
|
+
// DEFAULT ADAPTERS FACTORY
|
|
64
|
+
// Works out-of-the-box if your API matches VSDefaultPaginatedResponse /
|
|
65
|
+
// VSDefaultSingleResponse. Zero config needed in that case.
|
|
66
|
+
// ============================================================================
|
|
67
|
+
|
|
68
|
+
export function createDefaultAdapters<TBase, TDetail>(): VSAdapters<
|
|
69
|
+
VSDefaultPaginatedResponse<TBase>,
|
|
70
|
+
TBase,
|
|
71
|
+
VSDefaultSingleResponse<TDetail>,
|
|
72
|
+
TDetail
|
|
73
|
+
> {
|
|
74
|
+
return {
|
|
75
|
+
fromList: (raw) => ({
|
|
76
|
+
items: raw.data.items,
|
|
77
|
+
pagination: {
|
|
78
|
+
page: raw.data.page,
|
|
79
|
+
limit: raw.data.limit,
|
|
80
|
+
totalPages: raw.data.totalPages,
|
|
81
|
+
totalDocuments: raw.data.totalDocuments,
|
|
82
|
+
},
|
|
83
|
+
}),
|
|
84
|
+
fromSingle: (raw) => raw.data,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wraps a Promise and returns a [error, null] | [null, data] tuple.
|
|
3
|
+
* Eliminates try/catch at the call site — Go-style error handling for TypeScript.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* const [err, data] = await catchError(fetchUser(id));
|
|
7
|
+
* if (err) { // handle error }
|
|
8
|
+
* // data is correctly typed as T here
|
|
9
|
+
*/
|
|
10
|
+
export async function catchError<T>(
|
|
11
|
+
promise: Promise<T>
|
|
12
|
+
): Promise<[Error, null] | [null, T]> {
|
|
13
|
+
try {
|
|
14
|
+
const data = await promise;
|
|
15
|
+
return [null, data];
|
|
16
|
+
} catch (error) {
|
|
17
|
+
if (error instanceof Error) return [error, null];
|
|
18
|
+
return [new Error(String(error)), null];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@void-snippets/react",
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "TanStack Query resource hooks factory, Socket.IO hooks factory, type-safe routing contract, and general-purpose React hooks",
|
|
5
|
+
"homepage": "https://void-snippets.vercel.app",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/shahtirthhh/void-snippets.git",
|
|
9
|
+
"directory": "packages/react"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/shahtirthhh/void-snippets/issues"
|
|
13
|
+
},
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"module": "./dist/index.mjs",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"import": "./dist/index.mjs",
|
|
20
|
+
"require": "./dist/index.js",
|
|
21
|
+
"default": "./dist/index.mjs"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsup",
|
|
29
|
+
"dev": "tsup --watch"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"react",
|
|
33
|
+
"tanstack-query",
|
|
34
|
+
"react-query",
|
|
35
|
+
"hooks",
|
|
36
|
+
"api",
|
|
37
|
+
"socket.io",
|
|
38
|
+
"websocket",
|
|
39
|
+
"routing",
|
|
40
|
+
"react-router",
|
|
41
|
+
"type-safe",
|
|
42
|
+
"void-snippets",
|
|
43
|
+
"createResourceHooks",
|
|
44
|
+
"createSocketHooks",
|
|
45
|
+
"createRouteContract",
|
|
46
|
+
"useTypedSearchParams",
|
|
47
|
+
"useModal",
|
|
48
|
+
"usePagination",
|
|
49
|
+
"useAsyncState",
|
|
50
|
+
"useAlertMessage",
|
|
51
|
+
"useCallTimer"
|
|
52
|
+
],
|
|
53
|
+
"license": "MIT",
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"react": ">=17.0.0",
|
|
56
|
+
"@void-snippets/client": ">=0.1.0",
|
|
57
|
+
"socket.io-client": ">=4.6.0",
|
|
58
|
+
"react-router": ">=7.0.0"
|
|
59
|
+
},
|
|
60
|
+
"peerDependenciesMeta": {
|
|
61
|
+
"socket.io-client": {
|
|
62
|
+
"optional": true
|
|
63
|
+
},
|
|
64
|
+
"react-router": {
|
|
65
|
+
"optional": true
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"dependencies": {
|
|
69
|
+
"@tanstack/react-query": "^5.0.0",
|
|
70
|
+
"@void-snippets/core": "workspace:*"
|
|
71
|
+
},
|
|
72
|
+
"devDependencies": {
|
|
73
|
+
"@types/react": "^18.0.0",
|
|
74
|
+
"react": "^18.0.0",
|
|
75
|
+
"react-router": "^7.0.0",
|
|
76
|
+
"socket.io-client": "^4.7.0",
|
|
77
|
+
"tsup": "^8.0.0",
|
|
78
|
+
"typescript": "^5.4.0"
|
|
79
|
+
}
|
|
80
|
+
}
|