rastack 0.0.16 → 0.0.19

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 (105) hide show
  1. package/CHANGELOG.md +43874 -43013
  2. package/dist/.prettierrc +7 -7
  3. package/dist/compile/analyze.js +19 -11
  4. package/dist/compile/index.js +26 -17
  5. package/dist/compile/manifest.js +2 -3
  6. package/dist/compile/openapi.js +5 -8
  7. package/dist/compile/program.js +19 -10
  8. package/dist/csv-schema.js +5 -6
  9. package/dist/define/index.js +2 -2
  10. package/dist/entity-generation/delete-method.js +8 -10
  11. package/dist/entity-generation/form.js +80 -82
  12. package/dist/entity-generation/get-method.js +35 -36
  13. package/dist/entity-generation/imports.js +24 -20
  14. package/dist/entity-generation/sync-method.d.ts +1 -1
  15. package/dist/entity-generation/sync-method.js +45 -46
  16. package/dist/entity-generation/update-method.js +9 -10
  17. package/dist/rad-wasm-build.d.ts +1 -1
  18. package/dist/rad-wasm-build.js +15 -6
  19. package/dist/rad.js +9 -2
  20. package/dist/schema/camel-to-pastel.js +1 -2
  21. package/dist/schema/capitalise-first-letter.js +1 -2
  22. package/dist/schema/extract-response.js +3 -4
  23. package/dist/schema/fetch-schema.js +4 -16
  24. package/dist/schema/remove-non-model-paths.js +1 -2
  25. package/dist/schema/to-camel-case.js +1 -2
  26. package/dist/schema/to-pastel-case.js +1 -2
  27. package/dist/schema-convert.js +22 -33
  28. package/dist/schema-entities.js +177 -189
  29. package/dist/schema-fetch.js +46 -63
  30. package/dist/schema-full.js +23 -36
  31. package/dist/schema-index.js +16 -27
  32. package/dist/schema-params.js +11 -22
  33. package/dist/seed.js +95 -97
  34. package/hooks/form/form.ts +207 -207
  35. package/hooks/form/index.ts +8 -8
  36. package/hooks/form/interfaces.ts +217 -217
  37. package/hooks/form/structure.ts +39 -39
  38. package/hooks/form/validate-schema.ts +49 -49
  39. package/hooks/index.ts +3 -3
  40. package/hooks/query/api.ts +42 -42
  41. package/hooks/query/delete.ts +45 -45
  42. package/hooks/query/fetch.ts +48 -48
  43. package/hooks/query/index.ts +21 -21
  44. package/hooks/query/interfaces.ts +111 -111
  45. package/hooks/query/list.ts +286 -286
  46. package/hooks/query/update.ts +88 -88
  47. package/hooks/query/url.ts +31 -31
  48. package/hooks/real-time/index.ts +1 -1
  49. package/hooks/real-time/pusher.ts +43 -43
  50. package/jest.config.cjs +6 -6
  51. package/package.json +57 -57
  52. package/provider/index.ts +13 -13
  53. package/provider/provider.tsx +187 -187
  54. package/provider/types.ts +114 -114
  55. package/provider/warehouse.ts +167 -167
  56. package/provider/wasm.ts +124 -124
  57. package/runtime.ts +3 -3
  58. package/src/.prettierrc +7 -7
  59. package/src/compile/analyze.ts +224 -224
  60. package/src/compile/index.ts +86 -86
  61. package/src/compile/manifest.ts +10 -10
  62. package/src/compile/model.ts +69 -69
  63. package/src/compile/openapi.ts +266 -266
  64. package/src/compile/program.ts +40 -40
  65. package/src/csv-schema.ts +187 -187
  66. package/src/define/index.ts +162 -162
  67. package/src/entity-generation/delete-method.ts +37 -37
  68. package/src/entity-generation/form.ts +169 -169
  69. package/src/entity-generation/get-method.ts +80 -80
  70. package/src/entity-generation/imports.ts +110 -110
  71. package/src/entity-generation/sync-method.ts +222 -222
  72. package/src/entity-generation/update-method.ts +38 -38
  73. package/src/index.ts +77 -77
  74. package/src/rad-compile.ts +88 -88
  75. package/src/rad-wasm-build.ts +102 -102
  76. package/src/rad.ts +101 -101
  77. package/src/scan.ts +89 -89
  78. package/src/schema/camel-to-pastel.ts +3 -3
  79. package/src/schema/capitalise-first-letter.ts +3 -3
  80. package/src/schema/extract-response.ts +38 -38
  81. package/src/schema/fetch-schema.ts +12 -12
  82. package/src/schema/remove-non-model-paths.ts +13 -13
  83. package/src/schema/to-camel-case.ts +7 -7
  84. package/src/schema/to-pastel-case.ts +6 -6
  85. package/src/schema-convert.ts +61 -61
  86. package/src/schema-entities.ts +401 -401
  87. package/src/schema-fetch.ts +82 -82
  88. package/src/schema-full.ts +38 -38
  89. package/src/schema-index.ts +29 -29
  90. package/src/schema-params.ts +116 -116
  91. package/src/seed.ts +297 -297
  92. package/sync/engine.ts +392 -392
  93. package/sync/hooks.ts +450 -450
  94. package/sync/index.ts +8 -8
  95. package/sync/persistence.ts +237 -237
  96. package/sync/provider.tsx +91 -91
  97. package/sync/registry.ts +36 -36
  98. package/sync/store.ts +126 -126
  99. package/sync/transactions.ts +300 -300
  100. package/sync/types.ts +94 -94
  101. package/test/compile.spec.ts +192 -192
  102. package/test/csv-schema.spec.ts +143 -143
  103. package/test/schema-entities.spec.ts +688 -688
  104. package/tsconfig.json +24 -24
  105. package/types.ts +18 -18
@@ -1,88 +1,88 @@
1
- import { AxiosResponse } from "axios";
2
- import { useMutation, useQueryClient } from "react-query";
3
- import { IUpdateQueryResult, WriteQueryVariables } from "./interfaces";
4
- import { API } from "./api";
5
- import { stringifyQueryParams } from "./url";
6
-
7
- interface UpdateQueryProps<TParam> {
8
- putUrl?: ((params: TParam) => string) | string;
9
- patchUrl?: ((params: TParam) => string) | string;
10
- postUrl?: ((params: TParam) => string) | string;
11
- listQueryCacheKey?: string | undefined;
12
- itemQueryCacheKey?: string | undefined;
13
- }
14
-
15
- export function useUpdateQuery<TParams, TPayload, TResult>({
16
- putUrl,
17
- patchUrl,
18
- postUrl,
19
- listQueryCacheKey,
20
- itemQueryCacheKey,
21
- }: UpdateQueryProps<TParams>): IUpdateQueryResult<TParams, TPayload, TResult> {
22
- if (!putUrl && !patchUrl && !postUrl) {
23
- throw new Error("Either putUrl, patchUrl, or postUrl must be provided");
24
- }
25
- const queryClient = useQueryClient();
26
-
27
- return useMutation<
28
- TResult,
29
- unknown,
30
- WriteQueryVariables<TParams, TPayload>,
31
- unknown
32
- >(({ params, payload }) => {
33
- return new Promise((resolve, reject) => {
34
- let urlType: "put" | "patch" | "post" = "patch";
35
- let url: string | undefined;
36
-
37
- if (putUrl) {
38
- url = typeof putUrl === "function" ? putUrl(params) : putUrl;
39
- urlType = "put";
40
- } else if (patchUrl) {
41
- url = typeof patchUrl === "function" ? patchUrl(params) : patchUrl;
42
- urlType = "patch";
43
- } else if (postUrl) {
44
- url = typeof postUrl === "function" ? postUrl(params) : postUrl;
45
- urlType = "post";
46
- }
47
-
48
- if (!url) {
49
- throw new Error("URL must be provided for the API call");
50
- }
51
-
52
- // @ts-ignore
53
- const urlParams = stringifyQueryParams([], params);
54
- const serverURL = `${url}${urlParams ? `?${urlParams}` : ""}`;
55
-
56
- const getAPIFunction = (
57
- urlType: string,
58
- url: string,
59
- payload: TPayload,
60
- ) => {
61
- switch (urlType) {
62
- case "put":
63
- return API.put(serverURL, payload);
64
- case "patch":
65
- return API.patch(serverURL, payload);
66
- case "post":
67
- return API.post(serverURL, payload);
68
- default:
69
- throw new Error("Invalid URL type");
70
- }
71
- };
72
-
73
- getAPIFunction(urlType, url, payload)
74
- .then((response: AxiosResponse<TResult>) => {
75
- if (itemQueryCacheKey) {
76
- queryClient.invalidateQueries([itemQueryCacheKey]);
77
- }
78
- if (listQueryCacheKey) {
79
- queryClient.invalidateQueries(listQueryCacheKey);
80
- }
81
- resolve(response.data);
82
- })
83
- .catch((error) => {
84
- reject(error);
85
- });
86
- });
87
- });
88
- }
1
+ import { AxiosResponse } from "axios";
2
+ import { useMutation, useQueryClient } from "react-query";
3
+ import { IUpdateQueryResult, WriteQueryVariables } from "./interfaces";
4
+ import { API } from "./api";
5
+ import { stringifyQueryParams } from "./url";
6
+
7
+ interface UpdateQueryProps<TParam> {
8
+ putUrl?: ((params: TParam) => string) | string;
9
+ patchUrl?: ((params: TParam) => string) | string;
10
+ postUrl?: ((params: TParam) => string) | string;
11
+ listQueryCacheKey?: string | undefined;
12
+ itemQueryCacheKey?: string | undefined;
13
+ }
14
+
15
+ export function useUpdateQuery<TParams, TPayload, TResult>({
16
+ putUrl,
17
+ patchUrl,
18
+ postUrl,
19
+ listQueryCacheKey,
20
+ itemQueryCacheKey,
21
+ }: UpdateQueryProps<TParams>): IUpdateQueryResult<TParams, TPayload, TResult> {
22
+ if (!putUrl && !patchUrl && !postUrl) {
23
+ throw new Error("Either putUrl, patchUrl, or postUrl must be provided");
24
+ }
25
+ const queryClient = useQueryClient();
26
+
27
+ return useMutation<
28
+ TResult,
29
+ unknown,
30
+ WriteQueryVariables<TParams, TPayload>,
31
+ unknown
32
+ >(({ params, payload }) => {
33
+ return new Promise((resolve, reject) => {
34
+ let urlType: "put" | "patch" | "post" = "patch";
35
+ let url: string | undefined;
36
+
37
+ if (putUrl) {
38
+ url = typeof putUrl === "function" ? putUrl(params) : putUrl;
39
+ urlType = "put";
40
+ } else if (patchUrl) {
41
+ url = typeof patchUrl === "function" ? patchUrl(params) : patchUrl;
42
+ urlType = "patch";
43
+ } else if (postUrl) {
44
+ url = typeof postUrl === "function" ? postUrl(params) : postUrl;
45
+ urlType = "post";
46
+ }
47
+
48
+ if (!url) {
49
+ throw new Error("URL must be provided for the API call");
50
+ }
51
+
52
+ // @ts-ignore
53
+ const urlParams = stringifyQueryParams([], params);
54
+ const serverURL = `${url}${urlParams ? `?${urlParams}` : ""}`;
55
+
56
+ const getAPIFunction = (
57
+ urlType: string,
58
+ url: string,
59
+ payload: TPayload,
60
+ ) => {
61
+ switch (urlType) {
62
+ case "put":
63
+ return API.put(serverURL, payload);
64
+ case "patch":
65
+ return API.patch(serverURL, payload);
66
+ case "post":
67
+ return API.post(serverURL, payload);
68
+ default:
69
+ throw new Error("Invalid URL type");
70
+ }
71
+ };
72
+
73
+ getAPIFunction(urlType, url, payload)
74
+ .then((response: AxiosResponse<TResult>) => {
75
+ if (itemQueryCacheKey) {
76
+ queryClient.invalidateQueries([itemQueryCacheKey]);
77
+ }
78
+ if (listQueryCacheKey) {
79
+ queryClient.invalidateQueries(listQueryCacheKey);
80
+ }
81
+ resolve(response.data);
82
+ })
83
+ .catch((error) => {
84
+ reject(error);
85
+ });
86
+ });
87
+ });
88
+ }
@@ -1,31 +1,31 @@
1
- export function stringifyQueryParams<TParam>(
2
- pathParameters: (keyof TParam)[],
3
- filteredQueryParams?: Partial<TParam>,
4
- ): string | undefined {
5
- if (!filteredQueryParams) return undefined;
6
-
7
- const urlParams = new URLSearchParams();
8
-
9
- for (const key in filteredQueryParams) {
10
- if (pathParameters.includes(key as any)) {
11
- continue;
12
- }
13
- if (Object.prototype.hasOwnProperty.call(filteredQueryParams, key)) {
14
- const value = filteredQueryParams[key];
15
-
16
- if (Array.isArray(value)) {
17
- value.forEach((item) => {
18
- if (item !== undefined && item !== null) {
19
- urlParams.append(key, item.toString());
20
- }
21
- });
22
- } else {
23
- if (value !== undefined && value !== null) {
24
- urlParams.set(key, value.toString());
25
- }
26
- }
27
- }
28
- }
29
-
30
- return urlParams.toString();
31
- }
1
+ export function stringifyQueryParams<TParam>(
2
+ pathParameters: (keyof TParam)[],
3
+ filteredQueryParams?: Partial<TParam>,
4
+ ): string | undefined {
5
+ if (!filteredQueryParams) return undefined;
6
+
7
+ const urlParams = new URLSearchParams();
8
+
9
+ for (const key in filteredQueryParams) {
10
+ if (pathParameters.includes(key as any)) {
11
+ continue;
12
+ }
13
+ if (Object.prototype.hasOwnProperty.call(filteredQueryParams, key)) {
14
+ const value = filteredQueryParams[key];
15
+
16
+ if (Array.isArray(value)) {
17
+ value.forEach((item) => {
18
+ if (item !== undefined && item !== null) {
19
+ urlParams.append(key, item.toString());
20
+ }
21
+ });
22
+ } else {
23
+ if (value !== undefined && value !== null) {
24
+ urlParams.set(key, value.toString());
25
+ }
26
+ }
27
+ }
28
+ }
29
+
30
+ return urlParams.toString();
31
+ }
@@ -1 +1 @@
1
- export { usePusher } from "./pusher";
1
+ export { usePusher } from "./pusher";
@@ -1,43 +1,43 @@
1
- import { useEffect } from "react";
2
- import { useSyncEngineOptional } from "../../sync/provider";
3
-
4
- export interface PusherWakeOptions {
5
- /** Channel to subscribe to. Defaults to "rad-sync". */
6
- channel?: string;
7
- /** Event name carrying sync notifications. Defaults to "sync". */
8
- event?: string;
9
- /** A connected Pusher client instance. */
10
- client?: any;
11
- }
12
-
13
- /**
14
- * Optional push transport for the sync engine. Given a connected Pusher
15
- * client (passed in, or found on `window.Pusher.instances`), subscribes to
16
- * a channel and wakes the engine whenever a sync event arrives — the engine
17
- * then pulls the actual changes over HTTP. Push is a latency optimization
18
- * only; the long-poll `/changes` loop stays the source of truth, so this
19
- * hook is always safe to omit.
20
- */
21
- export function usePusher(options?: PusherWakeOptions) {
22
- const engine = useSyncEngineOptional();
23
- const channelName = options?.channel || "rad-sync";
24
- const eventName = options?.event || "sync";
25
- const client =
26
- options?.client ??
27
- (typeof window !== "undefined"
28
- ? (window as any).Pusher?.instances?.[0]
29
- : undefined);
30
-
31
- useEffect(() => {
32
- if (!engine || !client) {
33
- return;
34
- }
35
- const channel = client.subscribe(channelName);
36
- const handler = () => engine.wake();
37
- channel.bind(eventName, handler);
38
- return () => {
39
- channel.unbind(eventName, handler);
40
- client.unsubscribe(channelName);
41
- };
42
- }, [engine, client, channelName, eventName]);
43
- }
1
+ import { useEffect } from "react";
2
+ import { useSyncEngineOptional } from "../../sync/provider";
3
+
4
+ export interface PusherWakeOptions {
5
+ /** Channel to subscribe to. Defaults to "rad-sync". */
6
+ channel?: string;
7
+ /** Event name carrying sync notifications. Defaults to "sync". */
8
+ event?: string;
9
+ /** A connected Pusher client instance. */
10
+ client?: any;
11
+ }
12
+
13
+ /**
14
+ * Optional push transport for the sync engine. Given a connected Pusher
15
+ * client (passed in, or found on `window.Pusher.instances`), subscribes to
16
+ * a channel and wakes the engine whenever a sync event arrives — the engine
17
+ * then pulls the actual changes over HTTP. Push is a latency optimization
18
+ * only; the long-poll `/changes` loop stays the source of truth, so this
19
+ * hook is always safe to omit.
20
+ */
21
+ export function usePusher(options?: PusherWakeOptions) {
22
+ const engine = useSyncEngineOptional();
23
+ const channelName = options?.channel || "rad-sync";
24
+ const eventName = options?.event || "sync";
25
+ const client =
26
+ options?.client ??
27
+ (typeof window !== "undefined"
28
+ ? (window as any).Pusher?.instances?.[0]
29
+ : undefined);
30
+
31
+ useEffect(() => {
32
+ if (!engine || !client) {
33
+ return;
34
+ }
35
+ const channel = client.subscribe(channelName);
36
+ const handler = () => engine.wake();
37
+ channel.bind(eventName, handler);
38
+ return () => {
39
+ channel.unbind(eventName, handler);
40
+ client.unsubscribe(channelName);
41
+ };
42
+ }, [engine, client, channelName, eventName]);
43
+ }
package/jest.config.cjs CHANGED
@@ -1,6 +1,6 @@
1
- module.exports = {
2
- preset: 'ts-jest',
3
- testEnvironment: 'node',
4
- testMatch: ['**/test/**/*.spec.ts'],
5
- moduleFileExtensions: ['ts', 'js'],
6
- };
1
+ module.exports = {
2
+ preset: 'ts-jest',
3
+ testEnvironment: 'node',
4
+ testMatch: ['**/test/**/*.spec.ts'],
5
+ moduleFileExtensions: ['ts', 'js'],
6
+ };
package/package.json CHANGED
@@ -1,57 +1,57 @@
1
- {
2
- "name": "rastack",
3
- "version": "0.0.16",
4
- "description": "",
5
- "main": "runtime.ts",
6
- "types": "runtime.ts",
7
- "bin": {
8
- "rastack": "dist/index.js",
9
- "rad": "dist/rad.js"
10
- },
11
- "publishConfig": {
12
- "access": "public"
13
- },
14
- "scripts": {
15
- "format": "prettier --write \"**/*.{ts,tsx,md}\"",
16
- "build": "tsc && cp src/.prettierrc dist/.prettierrc",
17
- "start": "node dist/index.js",
18
- "test": "jest"
19
- },
20
- "keywords": [],
21
- "author": "",
22
- "license": "ISC",
23
- "dependencies": {
24
- "@apidevtools/json-schema-ref-parser": "^15.4.0",
25
- "@tanstack/react-query": "^5.101.2",
26
- "@ts-stack/openapi-spec": "^3.1.5",
27
- "@types/json-schema": "^7.0.15",
28
- "@types/react": "^19.2.17",
29
- "ajv": "^8.20.0",
30
- "ajv-formats": "^3.0.1",
31
- "axios": "^1.16.0",
32
- "formik": "^2.4.9",
33
- "js-yaml": "^5.2.1",
34
- "json-schema": "^0.4.0",
35
- "json-schema-to-typescript": "^15.0.4",
36
- "jsonschema": "^1.5.0",
37
- "lodash": "^4.18.0",
38
- "luxon": "^3.7.2",
39
- "minimatch": "^10.2.5",
40
- "prettier": "^3.9.4",
41
- "react-query": "^3.39.3",
42
- "typescript": "^6.0.3",
43
- "usehooks-ts": "^3.1.1"
44
- },
45
- "peerDependencies": {
46
- "react": "^19.2.7"
47
- },
48
- "devDependencies": {
49
- "@types/jest": "^30.0.0",
50
- "@types/js-yaml": "^4.0.9",
51
- "@types/mocha": "^10.0.6",
52
- "@types/node": "^26.1.0",
53
- "eslint": "^10.6.0",
54
- "jest": "^30.4.2",
55
- "ts-jest": "^29.4.11"
56
- }
57
- }
1
+ {
2
+ "name": "rastack",
3
+ "version": "0.0.19",
4
+ "description": "",
5
+ "main": "runtime.ts",
6
+ "types": "runtime.ts",
7
+ "bin": {
8
+ "rastack": "dist/index.js",
9
+ "rad": "dist/rad.js"
10
+ },
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "scripts": {
15
+ "format": "prettier --write \"**/*.{ts,tsx,md}\"",
16
+ "build": "tsc && cp src/.prettierrc dist/.prettierrc",
17
+ "start": "node dist/index.js",
18
+ "test": "jest"
19
+ },
20
+ "keywords": [],
21
+ "author": "",
22
+ "license": "ISC",
23
+ "dependencies": {
24
+ "@apidevtools/json-schema-ref-parser": "^15.4.0",
25
+ "@tanstack/react-query": "^5.101.2",
26
+ "@ts-stack/openapi-spec": "^3.1.5",
27
+ "@types/json-schema": "^7.0.15",
28
+ "@types/react": "^19.2.17",
29
+ "ajv": "^8.20.0",
30
+ "ajv-formats": "^3.0.1",
31
+ "axios": "^1.16.0",
32
+ "formik": "^2.4.9",
33
+ "js-yaml": "^5.2.1",
34
+ "json-schema": "^0.4.0",
35
+ "json-schema-to-typescript": "^15.0.4",
36
+ "jsonschema": "^1.5.0",
37
+ "lodash": "^4.18.0",
38
+ "luxon": "^3.7.2",
39
+ "minimatch": "^10.2.5",
40
+ "prettier": "^3.9.4",
41
+ "react-query": "^3.39.3",
42
+ "typescript": "^6.0.3",
43
+ "usehooks-ts": "^3.1.1"
44
+ },
45
+ "peerDependencies": {
46
+ "react": "^19.2.7"
47
+ },
48
+ "devDependencies": {
49
+ "@types/jest": "^30.0.0",
50
+ "@types/js-yaml": "^4.0.9",
51
+ "@types/mocha": "^10.0.6",
52
+ "@types/node": "^26.1.0",
53
+ "eslint": "^10.6.0",
54
+ "jest": "^30.4.2",
55
+ "ts-jest": "^29.4.11"
56
+ }
57
+ }
package/provider/index.ts CHANGED
@@ -1,13 +1,13 @@
1
- export * from "./types";
2
- export * from "./provider";
3
- export {
4
- createWasmAdapter,
5
- createEngine,
6
- defaultEngineLoader,
7
- } from "./wasm";
8
- export {
9
- WarehousePersistence,
10
- seedFromIceberg,
11
- manifestResources,
12
- downloadBlob,
13
- } from "./warehouse";
1
+ export * from "./types";
2
+ export * from "./provider";
3
+ export {
4
+ createWasmAdapter,
5
+ createEngine,
6
+ defaultEngineLoader,
7
+ } from "./wasm";
8
+ export {
9
+ WarehousePersistence,
10
+ seedFromIceberg,
11
+ manifestResources,
12
+ downloadBlob,
13
+ } from "./warehouse";