@gostack-framework/react 0.0.0-stage → 0.1.0

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 (138) hide show
  1. package/dist/api.d.ts +83 -0
  2. package/dist/api.js +170 -0
  3. package/dist/api.js.map +1 -0
  4. package/dist/auth.d.ts +60 -0
  5. package/dist/auth.js +136 -0
  6. package/dist/auth.js.map +1 -0
  7. package/dist/data.d.ts +25 -0
  8. package/dist/data.js +73 -0
  9. package/dist/data.js.map +1 -0
  10. package/dist/examples.d.ts +6 -0
  11. package/dist/examples.js +47 -0
  12. package/dist/examples.js.map +1 -0
  13. package/dist/hooks.d.ts +58 -0
  14. package/dist/hooks.js +109 -0
  15. package/dist/hooks.js.map +1 -0
  16. package/dist/index.d.ts +20 -0
  17. package/dist/index.js +21 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/layouts.d.ts +6 -0
  20. package/dist/layouts.js +34 -0
  21. package/dist/layouts.js.map +1 -0
  22. package/dist/line-flow/bus.d.ts +13 -0
  23. package/dist/line-flow/bus.js +52 -0
  24. package/dist/line-flow/bus.js.map +1 -0
  25. package/dist/line-flow/derived-line.d.ts +21 -0
  26. package/dist/line-flow/derived-line.js +122 -0
  27. package/dist/line-flow/derived-line.js.map +1 -0
  28. package/dist/line-flow/errors.d.ts +62 -0
  29. package/dist/line-flow/errors.js +91 -0
  30. package/dist/line-flow/errors.js.map +1 -0
  31. package/dist/line-flow/event-line.d.ts +16 -0
  32. package/dist/line-flow/event-line.js +81 -0
  33. package/dist/line-flow/event-line.js.map +1 -0
  34. package/dist/line-flow/index.d.ts +11 -0
  35. package/dist/line-flow/index.js +11 -0
  36. package/dist/line-flow/index.js.map +1 -0
  37. package/dist/line-flow/interchange.d.ts +17 -0
  38. package/dist/line-flow/interchange.js +86 -0
  39. package/dist/line-flow/interchange.js.map +1 -0
  40. package/dist/line-flow/lineflow.d.ts +12 -0
  41. package/dist/line-flow/lineflow.js +15 -0
  42. package/dist/line-flow/lineflow.js.map +1 -0
  43. package/dist/line-flow/network.d.ts +28 -0
  44. package/dist/line-flow/network.js +165 -0
  45. package/dist/line-flow/network.js.map +1 -0
  46. package/dist/line-flow/react/bridge.d.ts +23 -0
  47. package/dist/line-flow/react/bridge.js +40 -0
  48. package/dist/line-flow/react/bridge.js.map +1 -0
  49. package/dist/line-flow/react/hooks.d.ts +29 -0
  50. package/dist/line-flow/react/hooks.js +117 -0
  51. package/dist/line-flow/react/hooks.js.map +1 -0
  52. package/dist/line-flow/react/index.d.ts +3 -0
  53. package/dist/line-flow/react/index.js +4 -0
  54. package/dist/line-flow/react/index.js.map +1 -0
  55. package/dist/line-flow/react/provider.d.ts +15 -0
  56. package/dist/line-flow/react/provider.js +25 -0
  57. package/dist/line-flow/react/provider.js.map +1 -0
  58. package/dist/line-flow/scope.d.ts +21 -0
  59. package/dist/line-flow/scope.js +157 -0
  60. package/dist/line-flow/scope.js.map +1 -0
  61. package/dist/line-flow/state-line.d.ts +21 -0
  62. package/dist/line-flow/state-line.js +106 -0
  63. package/dist/line-flow/state-line.js.map +1 -0
  64. package/dist/line-flow/taxi.d.ts +15 -0
  65. package/dist/line-flow/taxi.js +81 -0
  66. package/dist/line-flow/taxi.js.map +1 -0
  67. package/dist/line-flow/types.d.ts +222 -0
  68. package/dist/line-flow/types.js +2 -0
  69. package/dist/line-flow/types.js.map +1 -0
  70. package/dist/line-flow/utils.d.ts +24 -0
  71. package/dist/line-flow/utils.js +53 -0
  72. package/dist/line-flow/utils.js.map +1 -0
  73. package/dist/paramsSerializer.d.ts +87 -0
  74. package/dist/paramsSerializer.js +138 -0
  75. package/dist/paramsSerializer.js.map +1 -0
  76. package/dist/registry.d.ts +10 -0
  77. package/dist/registry.js +115 -0
  78. package/dist/registry.js.map +1 -0
  79. package/dist/runtime.d.ts +80 -0
  80. package/dist/runtime.js +442 -0
  81. package/dist/runtime.js.map +1 -0
  82. package/dist/schemas.d.ts +88 -0
  83. package/dist/schemas.js +146 -0
  84. package/dist/schemas.js.map +1 -0
  85. package/dist/services.d.ts +35 -0
  86. package/dist/services.js +65 -0
  87. package/dist/services.js.map +1 -0
  88. package/dist/shared-types/file.types.d.ts +12 -0
  89. package/dist/shared-types/file.types.js +2 -0
  90. package/dist/shared-types/file.types.js.map +1 -0
  91. package/dist/shared-types/gallery.types.d.ts +22 -0
  92. package/dist/shared-types/gallery.types.js +2 -0
  93. package/dist/shared-types/gallery.types.js.map +1 -0
  94. package/dist/shared-types/governorates.types.d.ts +12 -0
  95. package/dist/shared-types/governorates.types.js +2 -0
  96. package/dist/shared-types/governorates.types.js.map +1 -0
  97. package/dist/shared-types/grade.types.d.ts +7 -0
  98. package/dist/shared-types/grade.types.js +2 -0
  99. package/dist/shared-types/grade.types.js.map +1 -0
  100. package/dist/shared-types/index.d.ts +13 -0
  101. package/dist/shared-types/index.js +14 -0
  102. package/dist/shared-types/index.js.map +1 -0
  103. package/dist/shared-types/metadata.types.d.ts +61 -0
  104. package/dist/shared-types/metadata.types.js +3 -0
  105. package/dist/shared-types/metadata.types.js.map +1 -0
  106. package/dist/shared-types/table.types.d.ts +33 -0
  107. package/dist/shared-types/table.types.js +2 -0
  108. package/dist/shared-types/table.types.js.map +1 -0
  109. package/dist/shared-types/viewCard.types.d.ts +78 -0
  110. package/dist/shared-types/viewCard.types.js +3 -0
  111. package/dist/shared-types/viewCard.types.js.map +1 -0
  112. package/dist/styles.css +347 -0
  113. package/dist/types.d.ts +126 -0
  114. package/dist/types.js +19 -0
  115. package/dist/types.js.map +1 -0
  116. package/dist/utils/conditionCompiler.d.ts +11 -0
  117. package/dist/utils/conditionCompiler.js +18 -0
  118. package/dist/utils/conditionCompiler.js.map +1 -0
  119. package/dist/utils/fileUtils.d.ts +50 -0
  120. package/dist/utils/fileUtils.js +266 -0
  121. package/dist/utils/fileUtils.js.map +1 -0
  122. package/dist/utils/metadataUtils.d.ts +35 -0
  123. package/dist/utils/metadataUtils.js +176 -0
  124. package/dist/utils/metadataUtils.js.map +1 -0
  125. package/dist/utils/normalizeTime.d.ts +1 -0
  126. package/dist/utils/normalizeTime.js +25 -0
  127. package/dist/utils/normalizeTime.js.map +1 -0
  128. package/dist/utils/tableUtils.d.ts +9 -0
  129. package/dist/utils/tableUtils.js +92 -0
  130. package/dist/utils/tableUtils.js.map +1 -0
  131. package/dist/utils/toFormData.d.ts +152 -0
  132. package/dist/utils/toFormData.js +250 -0
  133. package/dist/utils/toFormData.js.map +1 -0
  134. package/dist/utils/wizard.utils.d.ts +420 -0
  135. package/dist/utils/wizard.utils.js +596 -0
  136. package/dist/utils/wizard.utils.js.map +1 -0
  137. package/package.json +49 -3
  138. package/README.md +0 -3
@@ -0,0 +1,58 @@
1
+ import type { FieldValues, UseFormReturn, UseFormSetError } from "react-hook-form";
2
+ export declare function useLanguage(namespace?: string): {
3
+ t: import("i18next").TFunction<string, undefined>;
4
+ i18n: import("i18next").i18n;
5
+ currentLanguage: string;
6
+ isRTL: boolean;
7
+ changeLanguage: (language: string) => Promise<import("i18next").TFunction<"translation", undefined>>;
8
+ toggleLanguage: () => Promise<import("i18next").TFunction<"translation", undefined>>;
9
+ };
10
+ export declare function useDebounce<T>(value: T, delay?: number): T;
11
+ export declare function useListQueryState({ defaultPageSize, }?: {
12
+ defaultPageSize?: number;
13
+ }): {
14
+ page: number;
15
+ pageSize: number;
16
+ search: string;
17
+ sort: string;
18
+ filters: {
19
+ [k: string]: string;
20
+ };
21
+ queryParams: {
22
+ page: number;
23
+ perPage: number;
24
+ search: string | undefined;
25
+ sort: string | undefined;
26
+ filters: {
27
+ [k: string]: string;
28
+ };
29
+ };
30
+ setPage: (v: number) => void;
31
+ setPageSize: (v: number) => void;
32
+ setSearch: (v: string) => void;
33
+ setSort: (v: string) => void;
34
+ setFilter: (key: string, value: string) => void;
35
+ };
36
+ export declare function mapApiErrorToRHF<T extends FieldValues>(error: unknown, setError: UseFormSetError<T>): void;
37
+ export declare function useFormSubmit<T extends FieldValues, R>({ form, mutation, onSuccess, onError, resetOnSuccess, }: {
38
+ form: UseFormReturn<T>;
39
+ mutation: {
40
+ mutateAsync: (data: T) => Promise<R>;
41
+ isPending: boolean;
42
+ };
43
+ onSuccess?: (data: R) => void;
44
+ onError?: (error: unknown) => void;
45
+ resetOnSuccess?: boolean;
46
+ }): {
47
+ isSubmitting: boolean;
48
+ handleSubmit: (e?: React.BaseSyntheticEvent) => Promise<void | undefined>;
49
+ };
50
+ export declare function usePagination(total: number, pageSize?: number): {
51
+ page: number;
52
+ setPage: import("react").Dispatch<import("react").SetStateAction<number>>;
53
+ pageSize: number;
54
+ totalPages: number;
55
+ offset: number;
56
+ };
57
+ export declare function useTitle(title: string): void;
58
+ export declare function useFormApiErrors<T extends FieldValues>(setError: UseFormSetError<T>): (error: unknown) => void;
package/dist/hooks.js ADDED
@@ -0,0 +1,109 @@
1
+ import { useCallback, useEffect, useState } from "react";
2
+ import { useTranslation } from "react-i18next";
3
+ import { useSearchParams } from "react-router-dom";
4
+ import { normalizeApiError } from "./api.js";
5
+ export function useLanguage(namespace) {
6
+ const { t, i18n } = useTranslation(namespace);
7
+ return {
8
+ t,
9
+ i18n,
10
+ currentLanguage: i18n.language,
11
+ isRTL: i18n.dir() === "rtl",
12
+ changeLanguage: (language) => i18n.changeLanguage(language),
13
+ toggleLanguage: () => i18n.changeLanguage(i18n.language.startsWith("ar") ? "en" : "ar"),
14
+ };
15
+ }
16
+ export function useDebounce(value, delay = 300) {
17
+ const [debounced, setDebounced] = useState(value);
18
+ useEffect(() => {
19
+ const id = setTimeout(() => setDebounced(value), delay);
20
+ return () => clearTimeout(id);
21
+ }, [value, delay]);
22
+ return debounced;
23
+ }
24
+ export function useListQueryState({ defaultPageSize = 25, } = {}) {
25
+ const [params, setParams] = useSearchParams();
26
+ const positive = (value, fallback) => value && Number.isInteger(Number(value)) && Number(value) > 0
27
+ ? Number(value)
28
+ : fallback;
29
+ const page = positive(params.get("page"), 1);
30
+ const perPage = positive(params.get("perPage"), defaultPageSize);
31
+ const update = (key, value, reset = true) => setParams((previous) => {
32
+ const next = new URLSearchParams(previous);
33
+ if (value)
34
+ next.set(key, value);
35
+ else
36
+ next.delete(key);
37
+ if (reset)
38
+ next.delete("page");
39
+ return next;
40
+ });
41
+ const filters = Object.fromEntries([...params]
42
+ .filter(([key]) => key.startsWith("filter["))
43
+ .map(([key, value]) => [key.slice(7, -1), value]));
44
+ return {
45
+ page,
46
+ pageSize: perPage,
47
+ search: params.get("search") ?? "",
48
+ sort: params.get("sort") ?? "",
49
+ filters,
50
+ queryParams: {
51
+ page,
52
+ perPage,
53
+ search: params.get("search") || undefined,
54
+ sort: params.get("sort") || undefined,
55
+ filters,
56
+ },
57
+ setPage: (v) => update("page", String(v), false),
58
+ setPageSize: (v) => update("perPage", String(v)),
59
+ setSearch: (v) => update("search", v),
60
+ setSort: (v) => update("sort", v),
61
+ setFilter: (key, value) => update(`filter[${key}]`, value),
62
+ };
63
+ }
64
+ export function mapApiErrorToRHF(error, setError) {
65
+ const normalized = normalizeApiError(error);
66
+ for (const [field, messages] of Object.entries(normalized.validationErrors))
67
+ setError(field, { type: "server", message: messages.join(" ") });
68
+ setError("root.server", { type: "server", message: normalized.message });
69
+ }
70
+ export function useFormSubmit({ form, mutation, onSuccess, onError, resetOnSuccess = false, }) {
71
+ return {
72
+ isSubmitting: mutation.isPending || form.formState.isSubmitting,
73
+ handleSubmit: form.handleSubmit(async (data) => {
74
+ try {
75
+ const result = await mutation.mutateAsync(data);
76
+ if (resetOnSuccess)
77
+ form.reset();
78
+ onSuccess?.(result);
79
+ }
80
+ catch (error) {
81
+ mapApiErrorToRHF(error, form.setError);
82
+ onError?.(error);
83
+ }
84
+ }),
85
+ };
86
+ }
87
+ export function usePagination(total, pageSize = 25) {
88
+ const [page, setPage] = useState(1);
89
+ return {
90
+ page,
91
+ setPage,
92
+ pageSize,
93
+ totalPages: Math.max(1, Math.ceil(total / pageSize)),
94
+ offset: (page - 1) * pageSize,
95
+ };
96
+ }
97
+ export function useTitle(title) {
98
+ useEffect(() => {
99
+ const previous = document.title;
100
+ document.title = title;
101
+ return () => {
102
+ document.title = previous;
103
+ };
104
+ }, [title]);
105
+ }
106
+ export function useFormApiErrors(setError) {
107
+ return useCallback((error) => mapApiErrorToRHF(error, setError), [setError]);
108
+ }
109
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export * from "./types";
2
+ export * from "./registry";
3
+ export * from "./auth";
4
+ export * from "./api";
5
+ export * from "./data";
6
+ export * from "./hooks";
7
+ export * from "./runtime";
8
+ export * from "./layouts";
9
+ export * from "./services";
10
+ export * from "./examples";
11
+ export * from "./schemas";
12
+ export * from "./utils/toFormData";
13
+ export * from "./utils/normalizeTime";
14
+ export * from "./utils/fileUtils";
15
+ export * from "./utils/tableUtils";
16
+ export * from "./utils/metadataUtils";
17
+ export * from "./utils/wizard.utils";
18
+ export * from "./utils/conditionCompiler";
19
+ export * from "./line-flow/index.js";
20
+ export * from "./line-flow/react/index.js";
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ export * from "./types.js";
2
+ export * from "./registry.js";
3
+ export * from "./auth.js";
4
+ export * from "./api.js";
5
+ export * from "./data.js";
6
+ export * from "./hooks.js";
7
+ export * from "./runtime.js";
8
+ export * from "./layouts.js";
9
+ export * from "./services.js";
10
+ export * from "./examples.js";
11
+ export * from "./schemas.js";
12
+ export * from "./utils/toFormData.js";
13
+ export * from "./utils/normalizeTime.js";
14
+ export * from "./utils/fileUtils.js";
15
+ export * from "./utils/tableUtils.js";
16
+ export * from "./utils/metadataUtils.js";
17
+ export * from "./utils/wizard.utils.js";
18
+ export * from "./utils/conditionCompiler.js";
19
+ export * from "./line-flow/index.js";
20
+ export * from "./line-flow/react/index.js";
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,4BAA4B,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { LayoutProps } from "./types";
2
+ export declare function DashboardLayout({ children }: LayoutProps): import("react").JSX.Element;
3
+ export declare function SiteLayout({ children }: LayoutProps): import("react").JSX.Element;
4
+ export declare function AuthLayout({ children }: LayoutProps): import("react").JSX.Element;
5
+ export declare const OnboardingLayout: typeof AuthLayout;
6
+ export declare function RootLayout({ children }: LayoutProps): import("react").JSX.Element;
@@ -0,0 +1,34 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { Link, NavLink, Outlet } from "react-router-dom";
4
+ import { useAuth } from "./auth.js";
5
+ import { useLanguage } from "./hooks.js";
6
+ import { useBreadcrumbs, useDashboardTheme, useGoStack, useNavItems, } from "./runtime.js";
7
+ export function DashboardLayout({ children }) {
8
+ const { config } = useGoStack();
9
+ const nav = useNavItems();
10
+ const auth = useAuth();
11
+ const { t, toggleLanguage } = useLanguage();
12
+ const { t: common } = useLanguage("gostack");
13
+ const { darkMode, toggleTheme } = useDashboardTheme();
14
+ const crumbs = useBreadcrumbs();
15
+ const [open, setOpen] = useState(false);
16
+ const renderItems = (items) => items.map((item) => (_jsxs("div", { children: [_jsxs(NavLink, { to: item.href, end: true, onClick: () => setOpen(false), className: ({ isActive }) => `gs-nav-link${isActive ? " active" : ""}`, children: [item.icon ? (_jsx(item.icon, { size: 16 })) : (_jsx("span", { className: "gs-nav-dot" })), _jsx("span", { children: item.labelKey ? t(item.labelKey) : item.label })] }), item.children && (_jsx("div", { className: "gs-nav-children", children: renderItems(item.children) }))] }, item.key)));
17
+ return (_jsxs("div", { className: "gs-shell", children: [_jsxs("header", { className: "gs-topbar", children: [_jsx("button", { className: "gs-icon-button", "aria-label": common("menu"), "aria-expanded": open, onClick: () => setOpen(!open), children: "\u2630" }), _jsxs(Link, { className: "gs-brand", to: "/", children: [config.logo ? (_jsx("img", { src: config.logo, alt: "" })) : (_jsx("span", { className: "gs-mark", children: "G" })), config.name] }), _jsx("div", { className: "gs-header-slot", children: config.slots?.header }), _jsx("button", { className: "gs-icon-button", onClick: () => void toggleLanguage(), children: common("language") }), _jsx("button", { className: "gs-icon-button", "aria-label": common("theme"), onClick: toggleTheme, children: darkMode ? "☀" : "☾" }), auth.session ? (_jsx("button", { className: "gs-icon-button", onClick: () => void auth
18
+ .logout()
19
+ .catch((error) => config.onError?.(error, "logout")), children: common("logout") })) : config.auth ? (_jsx(Link, { to: config.auth.loginPath ?? "/auth/login", children: common("login") })) : null] }), _jsxs("div", { className: "gs-body", children: [open && (_jsx("button", { className: "gs-backdrop", "aria-label": common("menu"), onClick: () => setOpen(false) })), _jsxs("aside", { className: `gs-sidebar ${open ? "is-open" : ""}`, children: [_jsxs("div", { className: "gs-workspace-label", children: [_jsx("span", { className: "gs-workspace-avatar", children: config.name.slice(0, 1).toUpperCase() }), _jsxs("div", { children: [_jsx("strong", { children: config.name }), _jsx("small", { children: common("dashboard") })] })] }), _jsxs("nav", { "aria-label": common("dashboard"), children: [_jsxs(NavLink, { className: "gs-nav-link", to: "/", end: true, children: ["\u2302 ", _jsx("span", { children: common("home") })] }), nav.map((module) => (_jsxs("section", { className: "gs-nav-section", children: [_jsx("h2", { children: module.labelKey ? t(module.labelKey) : module.label }), renderItems(module.items)] }, module.id)))] }), _jsx("div", { className: "gs-sidebar-footer", children: config.slots?.sidebarFooter ?? _jsx("span", { children: "Powered by GoStack" }) })] }), _jsxs("main", { className: "gs-main", children: [_jsxs("div", { className: "gs-breadcrumbs", children: [_jsx(Link, { to: "/", children: common("home") }), crumbs.map((crumb, index) => (_jsxs("span", { children: [" ", "/ ", _jsx(Link, { to: crumb.path, children: crumb.label })] }, `${crumb.path}-${index}`)))] }), _jsx("div", { className: "gs-content", children: children ?? _jsx(Outlet, {}) })] })] })] }));
20
+ }
21
+ export function SiteLayout({ children }) {
22
+ const { config } = useGoStack();
23
+ const { t, toggleLanguage } = useLanguage("gostack");
24
+ useDashboardTheme();
25
+ return (_jsxs("div", { className: "gs-site", children: [_jsxs("header", { children: [_jsx(Link, { to: "/", className: "gs-brand", children: config.name }), _jsx("button", { onClick: () => void toggleLanguage(), children: t("language") })] }), _jsx("main", { children: children ?? _jsx(Outlet, {}) })] }));
26
+ }
27
+ export function AuthLayout({ children }) {
28
+ return (_jsx(SiteLayout, { children: _jsx("div", { className: "gs-auth-layout", children: children ?? _jsx(Outlet, {}) }) }));
29
+ }
30
+ export const OnboardingLayout = AuthLayout;
31
+ export function RootLayout({ children }) {
32
+ return _jsx(_Fragment, { children: children ?? _jsx(Outlet, {}) });
33
+ }
34
+ //# sourceMappingURL=layouts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layouts.js","sourceRoot":"","sources":["../src/layouts.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { Bus, BusOptions, Unsubscribe } from "./types.js";
2
+ export declare class BusImpl<TMessageMap extends object = Record<string, unknown>> implements Bus<TMessageMap> {
3
+ readonly id: string;
4
+ private readonly _channels;
5
+ private _isDisposed;
6
+ private readonly _onDispose?;
7
+ constructor(options?: BusOptions, onDispose?: () => void);
8
+ get isDisposed(): boolean;
9
+ private _getChannel;
10
+ publish<K extends keyof TMessageMap & string>(channel: K, payload: TMessageMap[K]): void;
11
+ subscribe<K extends keyof TMessageMap & string>(channel: K, listener: (payload: TMessageMap[K]) => void): Unsubscribe;
12
+ dispose(): void;
13
+ }
@@ -0,0 +1,52 @@
1
+ import { LineFlowDisposedError } from "./errors.js";
2
+ import { EventLineImpl } from "./event-line.js";
3
+ import { validateId, validateListener } from "./utils.js";
4
+ export class BusImpl {
5
+ id;
6
+ _channels = new Map();
7
+ _isDisposed = false;
8
+ _onDispose;
9
+ constructor(options, onDispose) {
10
+ this.id = options?.id ? validateId(options.id, "bus") : `bus:${Math.random().toString(36).slice(2, 9)}`;
11
+ this._onDispose = onDispose;
12
+ }
13
+ get isDisposed() {
14
+ return this._isDisposed;
15
+ }
16
+ _getChannel(channel) {
17
+ let line = this._channels.get(channel);
18
+ if (!line) {
19
+ line = new EventLineImpl({ id: `${this.id}:${channel}` });
20
+ this._channels.set(channel, line);
21
+ }
22
+ return line;
23
+ }
24
+ publish(channel, payload) {
25
+ if (this._isDisposed) {
26
+ throw new LineFlowDisposedError(`Cannot publish to disposed bus "${this.id}".`, this.id);
27
+ }
28
+ validateId(channel, "channel");
29
+ const line = this._getChannel(channel);
30
+ line.publish(payload);
31
+ }
32
+ subscribe(channel, listener) {
33
+ if (this._isDisposed) {
34
+ throw new LineFlowDisposedError(`Cannot subscribe to disposed bus "${this.id}".`, this.id);
35
+ }
36
+ validateId(channel, "channel");
37
+ validateListener(listener);
38
+ const line = this._getChannel(channel);
39
+ return line.subscribe(listener);
40
+ }
41
+ dispose() {
42
+ if (this._isDisposed)
43
+ return;
44
+ this._isDisposed = true;
45
+ for (const channelLine of this._channels.values()) {
46
+ channelLine.dispose();
47
+ }
48
+ this._channels.clear();
49
+ this._onDispose?.();
50
+ }
51
+ }
52
+ //# sourceMappingURL=bus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bus.js","sourceRoot":"","sources":["../../src/line-flow/bus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE1D,MAAM,OAAO,OAAO;IAGT,EAAE,CAAS;IACH,SAAS,GAAG,IAAI,GAAG,EAA8B,CAAC;IAC3D,WAAW,GAAG,KAAK,CAAC;IACX,UAAU,CAA4B;IAEvD,YAAY,OAAoB,EAAE,SAAsB;QACtD,IAAI,CAAC,EAAE,GAAG,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACxG,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;IAC9B,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAEO,WAAW,CAAC,OAAe;QACjC,IAAI,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,GAAG,IAAI,aAAa,CAAU,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,EAAE,IAAI,OAAO,EAAE,EAAE,CAAC,CAAC;YACnE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACpC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CAAuC,OAAU,EAAE,OAAuB;QAC/E,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,MAAM,IAAI,qBAAqB,CAAC,mCAAmC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3F,CAAC;QACD,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACvC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;IAED,SAAS,CACP,OAAU,EACV,QAA2C;QAE3C,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,MAAM,IAAI,qBAAqB,CAAC,qCAAqC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QAC7F,CAAC;QACD,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAC/B,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QAE3B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACvC,OAAO,IAAI,CAAC,SAAS,CAAC,QAAkC,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO;QACL,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAC7B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAExB,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;YAClD,WAAW,CAAC,OAAO,EAAE,CAAC;QACxB,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QACvB,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;IACtB,CAAC;CACF"}
@@ -0,0 +1,21 @@
1
+ import type { AnyStateLine, DerivedLine, DeriveLineOptions, Listener, Unsubscribe } from "./types.js";
2
+ export declare class DerivedLineImpl<T, const TDeps extends readonly AnyStateLine[]> implements DerivedLine<T> {
3
+ readonly id: string;
4
+ readonly kind: "derived";
5
+ readonly sources: TDeps;
6
+ private _snapshot;
7
+ private readonly _derive;
8
+ private readonly _equals;
9
+ private readonly _listeners;
10
+ private readonly _sourceUnsubscribes;
11
+ private _isDisposed;
12
+ private readonly _onDispose?;
13
+ constructor(options: DeriveLineOptions<T, TDeps>, onDispose?: () => void);
14
+ get isDisposed(): boolean;
15
+ getSnapshot(): T;
16
+ subscribe(listener: Listener<T>): Unsubscribe;
17
+ dispose(): void;
18
+ private _computeSnapshot;
19
+ private _handleSourceUpdate;
20
+ private static checkCycles;
21
+ }
@@ -0,0 +1,122 @@
1
+ import { LineFlowCycleError, LineFlowDisposedError, LineFlowSubscriberError, LineFlowValidationError, } from "./errors.js";
2
+ import { defaultEquals, notifyListeners, validateId, validateListener } from "./utils.js";
3
+ export class DerivedLineImpl {
4
+ id;
5
+ kind = "derived";
6
+ sources;
7
+ _snapshot;
8
+ _derive;
9
+ _equals;
10
+ _listeners = new Set();
11
+ _sourceUnsubscribes = [];
12
+ _isDisposed = false;
13
+ _onDispose;
14
+ constructor(options, onDispose) {
15
+ this.id = validateId(options?.id, "derived line");
16
+ if (!Array.isArray(options.sources) || options.sources.length === 0) {
17
+ throw new LineFlowValidationError(`Derived line "${this.id}" must have at least one source line.`);
18
+ }
19
+ if (typeof options.derive !== "function") {
20
+ throw new LineFlowValidationError(`Derived line "${this.id}" requires a derive function.`);
21
+ }
22
+ this.sources = options.sources;
23
+ this._derive = options.derive;
24
+ this._equals = options.equals ?? defaultEquals;
25
+ this._onDispose = onDispose;
26
+ // Validate that each source is a valid readable line
27
+ for (const source of this.sources) {
28
+ if (!source ||
29
+ typeof source !== "object" ||
30
+ typeof source.subscribe !== "function" ||
31
+ typeof source.getSnapshot !== "function") {
32
+ throw new LineFlowValidationError(`Derived line "${this.id}" source "${source?.id ?? String(source)}" is not a valid readable line.`);
33
+ }
34
+ }
35
+ // Validate cycle prevention
36
+ DerivedLineImpl.checkCycles(this.id, this.sources);
37
+ // Initial snapshot calculation
38
+ this._snapshot = this._computeSnapshot();
39
+ // Subscribe once to each distinct source line
40
+ const uniqueSources = Array.from(new Set(this.sources));
41
+ for (const source of uniqueSources) {
42
+ const unsub = source.subscribe(() => {
43
+ this._handleSourceUpdate();
44
+ });
45
+ this._sourceUnsubscribes.push(unsub);
46
+ }
47
+ }
48
+ get isDisposed() {
49
+ return this._isDisposed;
50
+ }
51
+ getSnapshot() {
52
+ return this._snapshot;
53
+ }
54
+ subscribe(listener) {
55
+ if (this._isDisposed) {
56
+ throw new LineFlowDisposedError(`Cannot subscribe to disposed derived line "${this.id}".`, this.id);
57
+ }
58
+ validateListener(listener);
59
+ this._listeners.add(listener);
60
+ let unsubscribed = false;
61
+ return () => {
62
+ if (unsubscribed)
63
+ return;
64
+ unsubscribed = true;
65
+ this._listeners.delete(listener);
66
+ };
67
+ }
68
+ dispose() {
69
+ if (this._isDisposed)
70
+ return;
71
+ this._isDisposed = true;
72
+ // Clean up upstream subscriptions
73
+ for (const unsub of this._sourceUnsubscribes) {
74
+ unsub();
75
+ }
76
+ this._sourceUnsubscribes.length = 0;
77
+ this._listeners.clear();
78
+ this._onDispose?.();
79
+ }
80
+ _computeSnapshot() {
81
+ const snapshots = this.sources.map((s) => s.getSnapshot());
82
+ return this._derive(snapshots);
83
+ }
84
+ _handleSourceUpdate() {
85
+ if (this._isDisposed)
86
+ return;
87
+ let next;
88
+ try {
89
+ next = this._computeSnapshot();
90
+ }
91
+ catch (err) {
92
+ throw new LineFlowSubscriberError(`Error computing derived value for line "${this.id}"`, [err]);
93
+ }
94
+ if (this._equals(this._snapshot, next)) {
95
+ return;
96
+ }
97
+ this._snapshot = next;
98
+ notifyListeners(this._listeners, this._snapshot, `derived line "${this.id}" recalculation`);
99
+ }
100
+ static checkCycles(targetId, sources) {
101
+ const visited = new Set();
102
+ function visit(line, path) {
103
+ if (!line || typeof line !== "object")
104
+ return;
105
+ if (line.id === targetId) {
106
+ throw new LineFlowCycleError([...path, targetId]);
107
+ }
108
+ if (visited.has(line.id))
109
+ return;
110
+ visited.add(line.id);
111
+ if ("sources" in line && Array.isArray(line.sources)) {
112
+ for (const upstream of line.sources) {
113
+ visit(upstream, [...path, line.id]);
114
+ }
115
+ }
116
+ }
117
+ for (const source of sources) {
118
+ visit(source, [targetId]);
119
+ }
120
+ }
121
+ }
122
+ //# sourceMappingURL=derived-line.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"derived-line.js","sourceRoot":"","sources":["../../src/line-flow/derived-line.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Base class for all LineFlow errors.
3
+ */
4
+ export declare class LineFlowError extends Error {
5
+ readonly code: string;
6
+ constructor(message: string, code: string);
7
+ }
8
+ /**
9
+ * Thrown when an ID is already registered within a network.
10
+ */
11
+ export declare class LineFlowDuplicateIdError extends LineFlowError {
12
+ readonly id: string;
13
+ constructor(id: string, entity?: string);
14
+ }
15
+ /**
16
+ * Thrown when an operation is performed on a disposed line, scope, or network.
17
+ */
18
+ export declare class LineFlowDisposedError extends LineFlowError {
19
+ readonly targetId?: string | undefined;
20
+ constructor(message: string, targetId?: string);
21
+ }
22
+ /**
23
+ * Thrown when one or more subscribers throw errors during notification dispatch.
24
+ */
25
+ export declare class LineFlowSubscriberError extends LineFlowError {
26
+ readonly errors: readonly unknown[];
27
+ constructor(message: string, errors: readonly unknown[]);
28
+ }
29
+ /**
30
+ * Thrown when runtime input validation fails.
31
+ */
32
+ export declare class LineFlowValidationError extends LineFlowError {
33
+ constructor(message: string);
34
+ }
35
+ /**
36
+ * Thrown when a Taxi request cannot find a registered handler for the task.
37
+ */
38
+ export declare class LineFlowMissingHandlerError extends LineFlowError {
39
+ readonly task: string;
40
+ constructor(task: string);
41
+ }
42
+ /**
43
+ * Thrown when attempting to register a duplicate handler for a Taxi task.
44
+ */
45
+ export declare class LineFlowDuplicateHandlerError extends LineFlowError {
46
+ readonly task: string;
47
+ constructor(task: string);
48
+ }
49
+ /**
50
+ * Thrown when a React hook requiring a LineFlowProvider is called outside one.
51
+ */
52
+ export declare class LineFlowProviderNotFoundError extends LineFlowError {
53
+ constructor();
54
+ }
55
+ /**
56
+ * Thrown when a circular dependency is detected among derived lines.
57
+ */
58
+ export declare class LineFlowCycleError extends LineFlowError {
59
+ readonly cycle: readonly string[];
60
+ constructor(cycle: readonly string[]);
61
+ }
62
+ export { LineFlowError as LineflowError, LineFlowDuplicateIdError as LineflowDuplicateIdError, LineFlowDisposedError as LineflowDisposedError, LineFlowSubscriberError as LineflowSubscriberError, LineFlowValidationError as LineflowValidationError, LineFlowMissingHandlerError as LineflowMissingHandlerError, LineFlowDuplicateHandlerError as LineflowDuplicateHandlerError, LineFlowProviderNotFoundError as LineflowProviderNotFoundError, LineFlowCycleError as LineflowCycleError, };