sgerp-frontend-lib 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 (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +70 -0
  3. package/dist/index.d.ts +7 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +8 -0
  6. package/dist/locales/locale_en.d.ts +2 -0
  7. package/dist/locales/locale_en.d.ts.map +1 -0
  8. package/dist/locales/locale_en.js +1933 -0
  9. package/dist/locales/locale_ja.d.ts +2 -0
  10. package/dist/locales/locale_ja.d.ts.map +1 -0
  11. package/dist/locales/locale_ja.js +1926 -0
  12. package/dist/locales/locale_ms.d.ts +2 -0
  13. package/dist/locales/locale_ms.d.ts.map +1 -0
  14. package/dist/locales/locale_ms.js +1916 -0
  15. package/dist/sgerp/client.d.ts +236 -0
  16. package/dist/sgerp/client.d.ts.map +1 -0
  17. package/dist/sgerp/collections/simulation/node.d.ts +11 -0
  18. package/dist/sgerp/collections/simulation/node.d.ts.map +1 -0
  19. package/dist/sgerp/collections/simulation/vehicle.d.ts +11 -0
  20. package/dist/sgerp/collections/simulation/vehicle.d.ts.map +1 -0
  21. package/dist/sgerp/context/sgerp-context.d.ts +54 -0
  22. package/dist/sgerp/context/sgerp-context.d.ts.map +1 -0
  23. package/dist/sgerp/hooks/use-collection.d.ts +83 -0
  24. package/dist/sgerp/hooks/use-collection.d.ts.map +1 -0
  25. package/dist/sgerp/hooks/use-live-updates.d.ts +35 -0
  26. package/dist/sgerp/hooks/use-live-updates.d.ts.map +1 -0
  27. package/dist/sgerp/hooks/use-live-updates.js +95 -0
  28. package/dist/sgerp/index.d.ts +90 -0
  29. package/dist/sgerp/index.d.ts.map +1 -0
  30. package/dist/sgerp/simulation-logic/fetchUtils.d.ts +69 -0
  31. package/dist/sgerp/simulation-logic/fetchUtils.d.ts.map +1 -0
  32. package/dist/sgerp/simulation-logic/index.d.ts +14 -0
  33. package/dist/sgerp/simulation-logic/index.d.ts.map +1 -0
  34. package/dist/sgerp/simulation-logic/index.js +11 -0
  35. package/dist/sgerp/simulation-logic/manualEditUtils.d.ts +70 -0
  36. package/dist/sgerp/simulation-logic/manualEditUtils.d.ts.map +1 -0
  37. package/dist/sgerp/simulation-logic/mapUtils.d.ts +11 -0
  38. package/dist/sgerp/simulation-logic/mapUtils.d.ts.map +1 -0
  39. package/dist/sgerp/simulation-logic/optimisticUpdateUtils.d.ts +28 -0
  40. package/dist/sgerp/simulation-logic/optimisticUpdateUtils.d.ts.map +1 -0
  41. package/dist/sgerp/simulation-logic/optimisticUpdateUtils.js +37 -0
  42. package/dist/sgerp/simulation-logic/referenceUtils.d.ts +28 -0
  43. package/dist/sgerp/simulation-logic/referenceUtils.d.ts.map +1 -0
  44. package/dist/sgerp/simulation-logic/routeCalculationUtils.d.ts +12 -0
  45. package/dist/sgerp/simulation-logic/routeCalculationUtils.d.ts.map +1 -0
  46. package/dist/sgerp/simulation-logic/timeShiftUtils.d.ts +27 -0
  47. package/dist/sgerp/simulation-logic/timeShiftUtils.d.ts.map +1 -0
  48. package/dist/sgerp/types/simulation/node.d.ts +102 -0
  49. package/dist/sgerp/types/simulation/node.d.ts.map +1 -0
  50. package/dist/sgerp/types/simulation/node.js +11 -0
  51. package/dist/sgerp/types/simulation/vehicle.d.ts +88 -0
  52. package/dist/sgerp/types/simulation/vehicle.d.ts.map +1 -0
  53. package/dist/sgerp/types/simulation/vehicle.js +1 -0
  54. package/dist/sgerp/utils/routeUtils.d.ts +47 -0
  55. package/dist/sgerp/utils/routeUtils.d.ts.map +1 -0
  56. package/package.json +126 -0
@@ -0,0 +1,236 @@
1
+ import type { SGERPConfig, Connection } from './types/config';
2
+ import type { User } from './types/account/user';
3
+ import type { Project } from './types/sharing/project';
4
+ import type { ProjectMember } from './types/sharing/project-member';
5
+ import type { Organization } from './types/sharing/organization';
6
+ import type { OrganizationProject } from './types/sharing/organization-project';
7
+ import type { Pricing } from './types/sharing/pricing';
8
+ import type { Passenger } from './types/transportation/passenger';
9
+ import type { Ticket } from './types/transportation/ticket';
10
+ import type { Transaction } from './types/transportation/transaction';
11
+ import type { Simulation } from './types/simulation/simulation';
12
+ import type { Driver } from './types/simulation/driver';
13
+ import type { Vehicle } from './types/simulation/vehicle';
14
+ import type { VehicleType } from './types/simulation/vehicletype';
15
+ import type { Booking } from './types/simulation/booking';
16
+ import type { Node } from './types/simulation/node';
17
+ import type { Dataset } from './types/simulation/dataset';
18
+ import type { SimulationProcessor } from './types/simulation/simulationprocessor';
19
+ import type { OperationsLocation } from './types/simulation/operationslocation';
20
+ import type { OperationsLocationGroup } from './types/simulation/operationslocationgroup';
21
+ import type { RoutingProfile } from './types/simulation/routingprofile';
22
+ import type { Geofence } from './types/simulation/geofence';
23
+ import type { MapboxToken } from './types/simulation/mapboxtoken';
24
+ import type { SMSScheduled } from './types/sms_notify/smsscheduled';
25
+ import type { TransitStop } from './types/masstransit/transitstop';
26
+ import type { Building } from './types/masstransit/building';
27
+ import type { TransitStopSet } from './types/masstransit/transitstopset';
28
+ import { ProjectCollection } from './collections/sharing/project';
29
+ import { ProjectMemberCollection } from './collections/sharing/project-member';
30
+ import { OrganizationCollection } from './collections/sharing/organization';
31
+ import { OrganizationProjectCollection } from './collections/sharing/organization-project';
32
+ import { PricingCollection } from './collections/sharing/pricing';
33
+ import { PassengerCollection } from './collections/transportation/passenger';
34
+ import { TicketCollection } from './collections/transportation/ticket';
35
+ import { TransactionCollection } from './collections/transportation/transaction';
36
+ import { UserCollection } from './collections/account/user';
37
+ import { SimulationCollection } from './collections/simulation/simulation';
38
+ import { DriverCollection } from './collections/simulation/driver';
39
+ import { VehicleCollection } from './collections/simulation/vehicle';
40
+ import { VehicleTypeCollection } from './collections/simulation/vehicletype';
41
+ import { BookingCollection } from './collections/simulation/booking';
42
+ import { NodeCollection } from './collections/simulation/node';
43
+ import { DatasetCollection } from './collections/simulation/dataset';
44
+ import { SimulationProcessorCollection } from './collections/simulation/simulationprocessor';
45
+ import { OperationsLocationCollection } from './collections/simulation/operationslocation';
46
+ import { OperationsLocationGroupCollection } from './collections/simulation/operationslocationgroup';
47
+ import { RoutingProfileCollection } from './collections/simulation/routingprofile';
48
+ import { GeofenceCollection } from './collections/simulation/geofence';
49
+ import { MapboxTokenCollection } from './collections/simulation/mapboxtoken';
50
+ import { SMSScheduledCollection } from './collections/sms_notify/smsscheduled';
51
+ import { TransitStopCollection } from './collections/masstransit/transitstop';
52
+ import { BuildingCollection } from './collections/masstransit/building';
53
+ import { TransitStopSetCollection } from './collections/masstransit/transitstopset';
54
+ import type { Collection } from './collection';
55
+ declare const COLLECTION_REGISTRY: {
56
+ readonly project: typeof ProjectCollection;
57
+ readonly projectmember: typeof ProjectMemberCollection;
58
+ readonly organization: typeof OrganizationCollection;
59
+ readonly organizationproject: typeof OrganizationProjectCollection;
60
+ readonly pricing: typeof PricingCollection;
61
+ readonly passenger: typeof PassengerCollection;
62
+ readonly ticket: typeof TicketCollection;
63
+ readonly transaction: typeof TransactionCollection;
64
+ readonly user: typeof UserCollection;
65
+ readonly simulation: typeof SimulationCollection;
66
+ readonly vehicle: typeof VehicleCollection;
67
+ readonly vehicletype: typeof VehicleTypeCollection;
68
+ readonly booking: typeof BookingCollection;
69
+ readonly node: typeof NodeCollection;
70
+ readonly driver: typeof DriverCollection;
71
+ readonly dataset: typeof DatasetCollection;
72
+ readonly simulationprocessor: typeof SimulationProcessorCollection;
73
+ readonly operationslocation: typeof OperationsLocationCollection;
74
+ readonly operationslocationgroup: typeof OperationsLocationGroupCollection;
75
+ readonly transitstop: typeof TransitStopCollection;
76
+ readonly routingprofile: typeof RoutingProfileCollection;
77
+ readonly geofence: typeof GeofenceCollection;
78
+ readonly mapboxtoken: typeof MapboxTokenCollection;
79
+ readonly smsscheduled: typeof SMSScheduledCollection;
80
+ readonly building: typeof BuildingCollection;
81
+ readonly transitstopset: typeof TransitStopSetCollection;
82
+ };
83
+ type CollectionType = keyof typeof COLLECTION_REGISTRY;
84
+ export type ModelTypeMap = {
85
+ project: Project;
86
+ projectmember: ProjectMember;
87
+ organization: Organization;
88
+ organizationproject: OrganizationProject;
89
+ pricing: Pricing;
90
+ passenger: Passenger;
91
+ ticket: Ticket;
92
+ transaction: Transaction;
93
+ user: User;
94
+ simulation: Simulation;
95
+ vehicle: Vehicle;
96
+ vehicletype: VehicleType;
97
+ booking: Booking;
98
+ node: Node;
99
+ driver: Driver;
100
+ dataset: Dataset;
101
+ simulationprocessor: SimulationProcessor;
102
+ operationslocation: OperationsLocation;
103
+ operationslocationgroup: OperationsLocationGroup;
104
+ transitstop: TransitStop;
105
+ routingprofile: RoutingProfile;
106
+ geofence: Geofence;
107
+ mapboxtoken: MapboxToken;
108
+ smsscheduled: SMSScheduled;
109
+ building: Building;
110
+ transitstopset: TransitStopSet;
111
+ };
112
+ /**
113
+ * Main SGERP API Client
114
+ */
115
+ export declare class SGERPClient {
116
+ private config;
117
+ private _collections?;
118
+ private _contextCollections;
119
+ constructor(config: SGERPConfig);
120
+ /**
121
+ * Get the currently active connection
122
+ */
123
+ getActiveConnection(): Connection;
124
+ /**
125
+ * Get all available connections
126
+ */
127
+ getAllConnections(): Connection[];
128
+ /**
129
+ * Get a specific connection by ID
130
+ */
131
+ getConnection(connectionId: string): Connection | undefined;
132
+ /**
133
+ * Switch to a different connection
134
+ */
135
+ switchConnection(connectionId: string): void;
136
+ /**
137
+ * Add a new connection
138
+ */
139
+ addConnection(connection: Connection): void;
140
+ /**
141
+ * Remove a connection
142
+ */
143
+ removeConnection(connectionId: string): void;
144
+ /**
145
+ * Update password for a connection
146
+ */
147
+ updateConnectionPassword(connectionId: string, password: string): void;
148
+ /**
149
+ * Get the global timeout value
150
+ */
151
+ getTimeout(): number;
152
+ /**
153
+ * Get the base URL for the active connection
154
+ */
155
+ getBaseUrl(): string;
156
+ /**
157
+ * Access collections via api.collections.project, api.collections.projectmember, api.collections.passenger, api.collections.user, or api.collections.simulation
158
+ *
159
+ * @example
160
+ * const projects = api.collections.project;
161
+ * await projects.fetch({ limit: 20 });
162
+ * const project = projects.get(1);
163
+ *
164
+ * @example
165
+ * const members = api.collections.projectmember;
166
+ * await members.fetch({ limit: 100 });
167
+ *
168
+ * @example
169
+ * const passengers = api.collections.passenger;
170
+ * await passengers.fetch({ limit: 50 });
171
+ *
172
+ * @example
173
+ * const simulations = api.collections.simulation;
174
+ * await simulations.fetch({ limit: 10 });
175
+ */
176
+ get collections(): {
177
+ project: ProjectCollection;
178
+ projectmember: ProjectMemberCollection;
179
+ organization: OrganizationCollection;
180
+ organizationproject: OrganizationProjectCollection;
181
+ pricing: PricingCollection;
182
+ passenger: PassengerCollection;
183
+ ticket: TicketCollection;
184
+ transaction: TransactionCollection;
185
+ user: UserCollection;
186
+ simulation: SimulationCollection;
187
+ vehicle: VehicleCollection;
188
+ vehicletype: VehicleTypeCollection;
189
+ booking: BookingCollection;
190
+ node: NodeCollection;
191
+ driver: DriverCollection;
192
+ dataset: DatasetCollection;
193
+ simulationprocessor: SimulationProcessorCollection;
194
+ operationslocation: OperationsLocationCollection;
195
+ operationslocationgroup: OperationsLocationGroupCollection;
196
+ transitstop: TransitStopCollection;
197
+ routingprofile: RoutingProfileCollection;
198
+ geofence: GeofenceCollection;
199
+ mapboxtoken: MapboxTokenCollection;
200
+ smsscheduled: SMSScheduledCollection;
201
+ building: BuildingCollection;
202
+ transitstopset: TransitStopSetCollection;
203
+ };
204
+ /**
205
+ * Get or create a context-specific collection instance
206
+ * Allows multiple independent collections of the same type
207
+ *
208
+ * @example
209
+ * // Get separate collections for services and templates
210
+ * const services = api.getCollection('simulation', 'services');
211
+ * const templates = api.getCollection('simulation', 'templates');
212
+ *
213
+ * // Each maintains its own data independently
214
+ * await services.fetch({ simulation_mode: 'service' });
215
+ * await templates.fetch({ simulation_mode: 'template' });
216
+ */
217
+ getCollection<T extends CollectionType>(modelType: T, context?: string): ModelTypeMap[T] extends infer U extends {
218
+ id: number | string;
219
+ } ? Collection<U> : never;
220
+ /**
221
+ * Create a new Collection instance for a model type
222
+ * @internal
223
+ */
224
+ private Collection;
225
+ /**
226
+ * Generic method to fetch models from the API
227
+ * @private
228
+ */
229
+ private getModels;
230
+ }
231
+ /**
232
+ * Initialize SGERP library and return a client instance
233
+ */
234
+ export declare function initializeSGERP(config: SGERPConfig): SGERPClient;
235
+ export {};
236
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../sgerplib/sgerp/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { Collection } from '../../collection';
2
+ import type { Node } from '../../types/simulation/node';
3
+ import type { SGERPListResponse } from '../../types/account/user';
4
+ import type { RequestConfig } from '../../types/config';
5
+ /**
6
+ * Collection class for Node models
7
+ */
8
+ export declare class NodeCollection extends Collection<Node> {
9
+ constructor(fetchFn: (params?: unknown, config?: RequestConfig) => Promise<SGERPListResponse<Node>>);
10
+ }
11
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../../sgerplib/sgerp/collections/simulation/node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD;;GAEG;AACH,qBAAa,cAAe,SAAQ,UAAU,CAAC,IAAI,CAAC;gBAEhD,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,aAAa,KAAK,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;CAI1F"}
@@ -0,0 +1,11 @@
1
+ import { Collection } from '../../collection';
2
+ import type { Vehicle } from '../../types/simulation/vehicle';
3
+ import type { SGERPListResponse } from '../../types/account/user';
4
+ import type { RequestConfig } from '../../types/config';
5
+ /**
6
+ * Collection class for Vehicle models
7
+ */
8
+ export declare class VehicleCollection extends Collection<Vehicle> {
9
+ constructor(fetchFn: (params?: unknown, config?: RequestConfig) => Promise<SGERPListResponse<Vehicle>>);
10
+ }
11
+ //# sourceMappingURL=vehicle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vehicle.d.ts","sourceRoot":"","sources":["../../../../sgerplib/sgerp/collections/simulation/vehicle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,UAAU,CAAC,OAAO,CAAC;gBAEtD,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,aAAa,KAAK,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;CAI7F"}
@@ -0,0 +1,54 @@
1
+ import React, { type ReactNode } from 'react';
2
+ import type { SGERPClient } from '../client';
3
+ export interface SGERPProviderProps {
4
+ children: ReactNode;
5
+ }
6
+ /**
7
+ * Provider component that creates a single SGERP API instance
8
+ * and shares it with all child components via React Context.
9
+ *
10
+ * This should wrap your entire application (e.g., in app/layout.tsx)
11
+ * to ensure the same API instance and collections persist across page navigations.
12
+ *
13
+ * The provider automatically re-initializes when the active connection changes
14
+ * (e.g., when user logs out and logs in with different credentials).
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * // app/layout.tsx
19
+ * import { SGERPProvider } from '@/sgerplib/sgerp/context/sgerp-context';
20
+ *
21
+ * export default function RootLayout({ children }) {
22
+ * return (
23
+ * <html>
24
+ * <body>
25
+ * <SGERPProvider>
26
+ * {children}
27
+ * </SGERPProvider>
28
+ * </body>
29
+ * </html>
30
+ * );
31
+ * }
32
+ * ```
33
+ */
34
+ export declare function SGERPProvider({ children }: SGERPProviderProps): React.JSX.Element;
35
+ /**
36
+ * Hook to access the shared SGERP API instance from context.
37
+ *
38
+ * Must be used within a SGERPProvider.
39
+ *
40
+ * @example
41
+ * ```tsx
42
+ * function MyComponent() {
43
+ * const api = useSGERPContext();
44
+ *
45
+ * if (!api) {
46
+ * return <div>Not connected</div>;
47
+ * }
48
+ *
49
+ * return <ProjectTable collection={api.collections.project} api={api} />;
50
+ * }
51
+ * ```
52
+ */
53
+ export declare function useSGERPContext(): SGERPClient | null;
54
+ //# sourceMappingURL=sgerp-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sgerp-context.d.ts","sourceRoot":"","sources":["../../../sgerplib/sgerp/context/sgerp-context.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAA2D,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAQ7C,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE,kBAAkB,qBAiD7D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,IAAI,WAAW,GAAG,IAAI,CAEpD"}
@@ -0,0 +1,83 @@
1
+ import type { Collection } from '../collection';
2
+ import type { SGERPClient } from '../client';
3
+ import type { ProjectCollection } from '../collections/sharing/project';
4
+ import type { ProjectMemberCollection } from '../collections/sharing/project-member';
5
+ import type { OrganizationCollection } from '../collections/sharing/organization';
6
+ import type { OrganizationProjectCollection } from '../collections/sharing/organization-project';
7
+ import type { PricingCollection } from '../collections/sharing/pricing';
8
+ import type { UserCollection } from '../collections/account/user';
9
+ import type { PassengerCollection } from '../collections/transportation/passenger';
10
+ import type { TicketCollection } from '../collections/transportation/ticket';
11
+ import type { TransactionCollection } from '../collections/transportation/transaction';
12
+ import type { SimulationCollection } from '../collections/simulation/simulation';
13
+ import type { DriverCollection } from '../collections/simulation/driver';
14
+ import type { VehicleCollection } from '../collections/simulation/vehicle';
15
+ import type { VehicleTypeCollection } from '../collections/simulation/vehicletype';
16
+ import type { BookingCollection } from '../collections/simulation/booking';
17
+ import type { NodeCollection } from '../collections/simulation/node';
18
+ import type { DatasetCollection } from '../collections/simulation/dataset';
19
+ import type { SimulationProcessorCollection } from '../collections/simulation/simulationprocessor';
20
+ import type { OperationsLocationCollection } from '../collections/simulation/operationslocation';
21
+ import type { OperationsLocationGroupCollection } from '../collections/simulation/operationslocationgroup';
22
+ import type { RoutingProfileCollection } from '../collections/simulation/routingprofile';
23
+ import type { GeofenceCollection } from '../collections/simulation/geofence';
24
+ import type { MapboxTokenCollection } from '../collections/simulation/mapboxtoken';
25
+ import type { SMSScheduledCollection } from '../collections/sms_notify/smsscheduled';
26
+ import type { TransitStopCollection } from '../collections/masstransit/transitstop';
27
+ import type { BuildingCollection } from '../collections/masstransit/building';
28
+ import type { TransitStopSetCollection } from '../collections/masstransit/transitstopset';
29
+ /**
30
+ * React hook to subscribe to collection changes
31
+ */
32
+ export declare function useCollection<T extends {
33
+ id: number | string;
34
+ }>(collection: Collection<T> | null): Collection<T> | null;
35
+ /**
36
+ * React-aware API wrapper with reactive collections
37
+ */
38
+ interface ReactiveAPI {
39
+ collections: {
40
+ project: ProjectCollection;
41
+ simulation: SimulationCollection;
42
+ user: UserCollection;
43
+ projectmember: ProjectMemberCollection;
44
+ organization: OrganizationCollection;
45
+ organizationproject: OrganizationProjectCollection;
46
+ pricing: PricingCollection;
47
+ passenger: PassengerCollection;
48
+ ticket: TicketCollection;
49
+ transaction: TransactionCollection;
50
+ driver: DriverCollection;
51
+ vehicle: VehicleCollection;
52
+ vehicletype: VehicleTypeCollection;
53
+ booking: BookingCollection;
54
+ node: NodeCollection;
55
+ dataset: DatasetCollection;
56
+ simulationprocessor: SimulationProcessorCollection;
57
+ operationslocation: OperationsLocationCollection;
58
+ operationslocationgroup: OperationsLocationGroupCollection;
59
+ transitstop: TransitStopCollection;
60
+ routingprofile: RoutingProfileCollection;
61
+ geofence: GeofenceCollection;
62
+ mapboxtoken: MapboxTokenCollection;
63
+ smsscheduled: SMSScheduledCollection;
64
+ building: BuildingCollection;
65
+ transitstopset: TransitStopSetCollection;
66
+ };
67
+ getCollection: SGERPClient['getCollection'];
68
+ }
69
+ /**
70
+ * React hook to initialize SGERP API with active connection
71
+ * Returns an API with reactive collections that automatically re-render
72
+ *
73
+ * IMPORTANT: This hook will prefer to use the API instance from SGERPContext
74
+ * if available (when wrapped in SGERPProvider). This ensures the same API
75
+ * instance and collections persist across page navigations, preventing
76
+ * unnecessary data refetching.
77
+ *
78
+ * If no context is available, falls back to creating a local instance
79
+ * (backward compatible behavior).
80
+ */
81
+ export declare function useSGERP(): ReactiveAPI | null;
82
+ export {};
83
+ //# sourceMappingURL=use-collection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-collection.d.ts","sourceRoot":"","sources":["../../../sgerplib/sgerp/hooks/use-collection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { Collection } from '../collection';
2
+ interface UseLiveUpdatesOptions {
3
+ /**
4
+ * Interval in milliseconds (default: 5000 = 5 seconds)
5
+ */
6
+ interval?: number;
7
+ /**
8
+ * Whether to enable live updates (default: true)
9
+ */
10
+ enabled?: boolean;
11
+ /**
12
+ * Additional params to pass to fetchUpdates
13
+ */
14
+ params?: Record<string, unknown>;
15
+ /**
16
+ * Use modified_at__gte instead of modified_at__gt (default: false)
17
+ * Set to true for backends that don't support __gt filter
18
+ */
19
+ useGte?: boolean;
20
+ /**
21
+ * Callback when updates are received
22
+ */
23
+ onUpdate?: (hasUpdates: boolean) => void;
24
+ }
25
+ /**
26
+ * Hook to enable periodic live updates for a collection
27
+ * Fetches incremental updates based on modified_at timestamp
28
+ *
29
+ * @returns trigger function to manually trigger an immediate update
30
+ */
31
+ export declare function useLiveUpdates<T extends {
32
+ id: number | string;
33
+ }>(collection: Collection<T> | null, options?: UseLiveUpdatesOptions): () => Promise<void>;
34
+ export {};
35
+ //# sourceMappingURL=use-live-updates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-live-updates.d.ts","sourceRoot":"","sources":["../../../sgerplib/sgerp/hooks/use-live-updates.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,UAAU,qBAAqB;IAC7B;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;CAC1C;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,EAC9D,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,EAChC,OAAO,GAAE,qBAA0B,GAClC,MAAM,OAAO,CAAC,IAAI,CAAC,CAmGrB"}
@@ -0,0 +1,95 @@
1
+ import { useEffect, useRef, useCallback } from 'react';
2
+ /**
3
+ * Hook to enable periodic live updates for a collection
4
+ * Fetches incremental updates based on modified_at timestamp
5
+ *
6
+ * @returns trigger function to manually trigger an immediate update
7
+ */
8
+ export function useLiveUpdates(collection, options = {}) {
9
+ const { interval = 5000, enabled = true, params = {}, useGte = false, onUpdate, } = options;
10
+ const intervalRef = useRef(null);
11
+ const paramsRef = useRef(params);
12
+ const useGteRef = useRef(useGte);
13
+ const collectionRef = useRef(collection);
14
+ const onUpdateRef = useRef(onUpdate);
15
+ // Update refs when they change
16
+ useEffect(() => {
17
+ paramsRef.current = params;
18
+ }, [params]);
19
+ useEffect(() => {
20
+ useGteRef.current = useGte;
21
+ }, [useGte]);
22
+ useEffect(() => {
23
+ collectionRef.current = collection;
24
+ }, [collection]);
25
+ useEffect(() => {
26
+ onUpdateRef.current = onUpdate;
27
+ }, [onUpdate]);
28
+ // Manual trigger function
29
+ const trigger = useCallback(async () => {
30
+ var _a;
31
+ const col = collectionRef.current;
32
+ if (!col)
33
+ return;
34
+ try {
35
+ // Check if fetchUpdates method exists
36
+ if (typeof col.fetchUpdates !== 'function') {
37
+ console.error('collection.fetchUpdates is not a function. Collection:', col);
38
+ console.error('Available methods:', Object.getOwnPropertyNames(Object.getPrototypeOf(col)));
39
+ return;
40
+ }
41
+ const hasUpdates = await col.fetchUpdates(paramsRef.current, useGteRef.current);
42
+ (_a = onUpdateRef.current) === null || _a === void 0 ? void 0 : _a.call(onUpdateRef, hasUpdates);
43
+ }
44
+ catch (error) {
45
+ // Suppress timeout errors - they're expected and will retry
46
+ if (error instanceof Error && error.message === 'Request timeout') {
47
+ return;
48
+ }
49
+ console.error('Manual live update trigger failed:', error);
50
+ }
51
+ }, []);
52
+ useEffect(() => {
53
+ if (!collection || !enabled) {
54
+ // Clear any existing interval
55
+ if (intervalRef.current) {
56
+ clearInterval(intervalRef.current);
57
+ intervalRef.current = null;
58
+ }
59
+ return;
60
+ }
61
+ // Start polling for updates
62
+ intervalRef.current = setInterval(async () => {
63
+ var _a;
64
+ const col = collectionRef.current;
65
+ if (!col)
66
+ return;
67
+ try {
68
+ if (typeof col.fetchUpdates !== 'function') {
69
+ console.error('collection.fetchUpdates is not a function. Collection:', col);
70
+ console.error('Available methods:', Object.getOwnPropertyNames(Object.getPrototypeOf(col)));
71
+ return;
72
+ }
73
+ const hasUpdates = await col.fetchUpdates(paramsRef.current, useGteRef.current);
74
+ (_a = onUpdateRef.current) === null || _a === void 0 ? void 0 : _a.call(onUpdateRef, hasUpdates);
75
+ }
76
+ catch (error) {
77
+ // Suppress timeout errors - they're expected and will retry on next interval
78
+ if (error instanceof Error && error.message === 'Request timeout') {
79
+ // Silent - timeouts are normal for live updates
80
+ return;
81
+ }
82
+ // Log other errors
83
+ console.error('Live update failed:', error);
84
+ }
85
+ }, interval);
86
+ // Cleanup on unmount or when dependencies change
87
+ return () => {
88
+ if (intervalRef.current) {
89
+ clearInterval(intervalRef.current);
90
+ intervalRef.current = null;
91
+ }
92
+ };
93
+ }, [collection, enabled, interval, onUpdate]);
94
+ return trigger;
95
+ }