@sudobility/mogulgame_lib 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.
- package/README.md +76 -0
- package/dist/business/hooks/index.d.ts +2 -0
- package/dist/business/hooks/index.d.ts.map +1 -0
- package/dist/business/hooks/index.js +2 -0
- package/dist/business/hooks/index.js.map +1 -0
- package/dist/business/hooks/useHistoriesManager.d.ts +25 -0
- package/dist/business/hooks/useHistoriesManager.d.ts.map +1 -0
- package/dist/business/hooks/useHistoriesManager.js +96 -0
- package/dist/business/hooks/useHistoriesManager.js.map +1 -0
- package/dist/business/index.d.ts +4 -0
- package/dist/business/index.d.ts.map +1 -0
- package/dist/business/index.js +4 -0
- package/dist/business/index.js.map +1 -0
- package/dist/business/stores/historiesStore.d.ts +19 -0
- package/dist/business/stores/historiesStore.d.ts.map +1 -0
- package/dist/business/stores/historiesStore.js +96 -0
- package/dist/business/stores/historiesStore.js.map +1 -0
- package/dist/business/stores/index.d.ts +2 -0
- package/dist/business/stores/index.d.ts.map +1 -0
- package/dist/business/stores/index.js +2 -0
- package/dist/business/stores/index.js.map +1 -0
- package/dist/business/utils/calculations.d.ts +4 -0
- package/dist/business/utils/calculations.d.ts.map +1 -0
- package/dist/business/utils/calculations.js +10 -0
- package/dist/business/utils/calculations.js.map +1 -0
- package/dist/business/utils/index.d.ts +3 -0
- package/dist/business/utils/index.d.ts.map +1 -0
- package/dist/business/utils/index.js +3 -0
- package/dist/business/utils/index.js.map +1 -0
- package/dist/business/utils/offers.d.ts +10 -0
- package/dist/business/utils/offers.d.ts.map +1 -0
- package/dist/business/utils/offers.js +40 -0
- package/dist/business/utils/offers.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +71 -0
package/README.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# @sudobility/starter_lib
|
|
2
|
+
|
|
3
|
+
Business logic library with Zustand stores for the Starter application.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @sudobility/starter_lib
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Peer dependencies:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
bun add react @tanstack/react-query zustand @sudobility/types
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { useHistoriesManager } from "@sudobility/starter_lib";
|
|
21
|
+
|
|
22
|
+
// In a React component:
|
|
23
|
+
const {
|
|
24
|
+
histories,
|
|
25
|
+
total,
|
|
26
|
+
percentage,
|
|
27
|
+
isCached,
|
|
28
|
+
createHistory,
|
|
29
|
+
updateHistory,
|
|
30
|
+
deleteHistory,
|
|
31
|
+
} = useHistoriesManager({
|
|
32
|
+
baseUrl: "https://api.example.com",
|
|
33
|
+
networkClient,
|
|
34
|
+
userId: "firebase-uid",
|
|
35
|
+
token: firebaseIdToken,
|
|
36
|
+
autoFetch: true, // default
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## API
|
|
41
|
+
|
|
42
|
+
### useHistoriesManager
|
|
43
|
+
|
|
44
|
+
Unified hook that combines starter_client hooks + Zustand store + business logic:
|
|
45
|
+
|
|
46
|
+
- Percentage calculation: `(userSum / globalTotal) * 100`
|
|
47
|
+
- Cache fallback: returns cached data while server hasn't responded
|
|
48
|
+
- Auto-fetch on mount (configurable)
|
|
49
|
+
- Token reactivity: resets state on token change
|
|
50
|
+
|
|
51
|
+
### useHistoriesStore
|
|
52
|
+
|
|
53
|
+
Zustand store providing per-user client-side cache with operations: `set`, `get`, `add`, `update`, `remove`. Keyed by user ID.
|
|
54
|
+
|
|
55
|
+
## Development
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
bun run build # Build ESM
|
|
59
|
+
bun run clean # Remove dist/
|
|
60
|
+
bun test # Run Vitest tests
|
|
61
|
+
bun run typecheck # TypeScript check
|
|
62
|
+
bun run lint # ESLint
|
|
63
|
+
bun run verify # All checks + build (use before commit)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Related Packages
|
|
67
|
+
|
|
68
|
+
- **starter_types** -- Shared type definitions (imported transitively via starter_client)
|
|
69
|
+
- **starter_client** -- API client SDK; this library wraps its hooks with business logic
|
|
70
|
+
- **starter_app** -- Web frontend that consumes `useHistoriesManager`
|
|
71
|
+
- **starter_app_rn** -- React Native app that consumes `useHistoriesManager`
|
|
72
|
+
- **starter_api** -- Backend server (communicated with indirectly through starter_client)
|
|
73
|
+
|
|
74
|
+
## License
|
|
75
|
+
|
|
76
|
+
BUSL-1.1
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/business/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,GAC/B,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/business/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,GAGpB,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { History, HistoryCreateRequest, HistoryUpdateRequest, Optional } from '@sudobility/mogulgame_types';
|
|
2
|
+
import type { NetworkClient } from '@sudobility/types';
|
|
3
|
+
import type { FirebaseIdToken } from '@sudobility/mogulgame_client';
|
|
4
|
+
export interface UseHistoriesManagerConfig {
|
|
5
|
+
baseUrl: string;
|
|
6
|
+
networkClient: NetworkClient;
|
|
7
|
+
userId: Optional<string>;
|
|
8
|
+
token: Optional<FirebaseIdToken>;
|
|
9
|
+
autoFetch?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface UseHistoriesManagerReturn {
|
|
12
|
+
histories: History[];
|
|
13
|
+
total: number;
|
|
14
|
+
percentage: number;
|
|
15
|
+
isLoading: boolean;
|
|
16
|
+
error: Optional<string>;
|
|
17
|
+
isCached: boolean;
|
|
18
|
+
cachedAt: Optional<number>;
|
|
19
|
+
createHistory: (data: HistoryCreateRequest) => Promise<void>;
|
|
20
|
+
updateHistory: (historyId: string, data: HistoryUpdateRequest) => Promise<void>;
|
|
21
|
+
deleteHistory: (historyId: string) => Promise<void>;
|
|
22
|
+
refresh: () => void;
|
|
23
|
+
}
|
|
24
|
+
export declare const useHistoriesManager: ({ baseUrl, networkClient, userId, token, autoFetch, }: UseHistoriesManagerConfig) => UseHistoriesManagerReturn;
|
|
25
|
+
//# sourceMappingURL=useHistoriesManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useHistoriesManager.d.ts","sourceRoot":"","sources":["../../../src/business/hooks/useHistoriesManager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,OAAO,EACP,oBAAoB,EACpB,oBAAoB,EACpB,QAAQ,EACT,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAmBpE,MAAM,WAAW,yBAAyB;IAExC,OAAO,EAAE,MAAM,CAAC;IAGhB,aAAa,EAAE,aAAa,CAAC;IAM7B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAOzB,KAAK,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;IAajC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAQD,MAAM,WAAW,yBAAyB;IAMxC,SAAS,EAAE,OAAO,EAAE,CAAC;IAMrB,KAAK,EAAE,MAAM,CAAC;IASd,UAAU,EAAE,MAAM,CAAC;IAMnB,SAAS,EAAE,OAAO,CAAC;IAUnB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IASxB,QAAQ,EAAE,OAAO,CAAC;IAMlB,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAS3B,aAAa,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAU7D,aAAa,EAAE,CACb,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,oBAAoB,KACvB,OAAO,CAAC,IAAI,CAAC,CAAC;IASnB,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAMpD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAmDD,eAAO,MAAM,mBAAmB,GAAI,uDAMjC,yBAAyB,KAAG,yBAwJ9B,CAAC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
2
|
+
import { useHistories, useHistoriesTotal } from '@sudobility/mogulgame_client';
|
|
3
|
+
import { useHistoriesStore } from '../stores/historiesStore';
|
|
4
|
+
import { calculatePercentage } from '../utils/calculations';
|
|
5
|
+
export const useHistoriesManager = ({ baseUrl, networkClient, userId, token, autoFetch = true, }) => {
|
|
6
|
+
const { histories: clientHistories, isLoading: historiesLoading, error: historiesError, update, createHistory: clientCreate, updateHistory: clientUpdate, deleteHistory: clientDelete, isCreating, isUpdating, isDeleting, } = useHistories(networkClient, baseUrl, userId ?? null, token ?? null);
|
|
7
|
+
const { total, isLoading: totalLoading, error: totalError, } = useHistoriesTotal(networkClient, baseUrl);
|
|
8
|
+
const cacheEntry = useHistoriesStore(useCallback(state => (userId ? state.cache[userId] : undefined), [userId]));
|
|
9
|
+
const setHistories = useHistoriesStore(state => state.setHistories);
|
|
10
|
+
const addHistoryToStore = useHistoriesStore(state => state.addHistory);
|
|
11
|
+
const updateHistoryInStore = useHistoriesStore(state => state.updateHistory);
|
|
12
|
+
const removeHistoryFromStore = useHistoriesStore(state => state.removeHistory);
|
|
13
|
+
const cachedHistories = cacheEntry?.histories;
|
|
14
|
+
const cachedAt = cacheEntry?.cachedAt;
|
|
15
|
+
const histories = useMemo(() => clientHistories.length > 0 ? clientHistories : (cachedHistories ?? []), [clientHistories, cachedHistories]);
|
|
16
|
+
const isCached = clientHistories.length === 0 && (cachedHistories?.length ?? 0) > 0;
|
|
17
|
+
const prevClientHistoriesRef = useRef(clientHistories);
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (clientHistories.length > 0 &&
|
|
20
|
+
userId &&
|
|
21
|
+
clientHistories !== prevClientHistoriesRef.current) {
|
|
22
|
+
prevClientHistoriesRef.current = clientHistories;
|
|
23
|
+
setHistories(userId, clientHistories);
|
|
24
|
+
}
|
|
25
|
+
}, [clientHistories, userId, setHistories]);
|
|
26
|
+
const percentage = useMemo(() => calculatePercentage(histories, total), [histories, total]);
|
|
27
|
+
const createHistory = useCallback(async (data) => {
|
|
28
|
+
const response = await clientCreate(data);
|
|
29
|
+
if (response.success && response.data && userId) {
|
|
30
|
+
addHistoryToStore(userId, response.data);
|
|
31
|
+
}
|
|
32
|
+
if (!response.success) {
|
|
33
|
+
throw new Error(response.error || 'Failed to create history');
|
|
34
|
+
}
|
|
35
|
+
}, [clientCreate, userId, addHistoryToStore]);
|
|
36
|
+
const updateHistory = useCallback(async (historyId, data) => {
|
|
37
|
+
const response = await clientUpdate(historyId, data);
|
|
38
|
+
if (response.success && response.data && userId) {
|
|
39
|
+
updateHistoryInStore(userId, historyId, response.data);
|
|
40
|
+
}
|
|
41
|
+
if (!response.success) {
|
|
42
|
+
throw new Error(response.error || 'Failed to update history');
|
|
43
|
+
}
|
|
44
|
+
}, [clientUpdate, userId, updateHistoryInStore]);
|
|
45
|
+
const deleteHistory = useCallback(async (historyId) => {
|
|
46
|
+
const response = await clientDelete(historyId);
|
|
47
|
+
if (response.success && userId) {
|
|
48
|
+
removeHistoryFromStore(userId, historyId);
|
|
49
|
+
}
|
|
50
|
+
if (!response.success) {
|
|
51
|
+
throw new Error(response.error || 'Failed to delete history');
|
|
52
|
+
}
|
|
53
|
+
}, [clientDelete, userId, removeHistoryFromStore]);
|
|
54
|
+
const isLoading = historiesLoading || totalLoading || isCreating || isUpdating || isDeleting;
|
|
55
|
+
const error = historiesError ?? totalError ?? null;
|
|
56
|
+
const hasAttemptedFetchRef = useRef(false);
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
if (autoFetch &&
|
|
59
|
+
token &&
|
|
60
|
+
userId &&
|
|
61
|
+
histories.length === 0 &&
|
|
62
|
+
!hasAttemptedFetchRef.current) {
|
|
63
|
+
hasAttemptedFetchRef.current = true;
|
|
64
|
+
update();
|
|
65
|
+
}
|
|
66
|
+
}, [autoFetch, token, userId, histories.length, update]);
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
hasAttemptedFetchRef.current = false;
|
|
69
|
+
}, [token]);
|
|
70
|
+
return useMemo(() => ({
|
|
71
|
+
histories,
|
|
72
|
+
total,
|
|
73
|
+
percentage,
|
|
74
|
+
isLoading,
|
|
75
|
+
error,
|
|
76
|
+
isCached,
|
|
77
|
+
cachedAt: cachedAt ?? null,
|
|
78
|
+
createHistory,
|
|
79
|
+
updateHistory,
|
|
80
|
+
deleteHistory,
|
|
81
|
+
refresh: update,
|
|
82
|
+
}), [
|
|
83
|
+
histories,
|
|
84
|
+
total,
|
|
85
|
+
percentage,
|
|
86
|
+
isLoading,
|
|
87
|
+
error,
|
|
88
|
+
isCached,
|
|
89
|
+
cachedAt,
|
|
90
|
+
createHistory,
|
|
91
|
+
updateHistory,
|
|
92
|
+
deleteHistory,
|
|
93
|
+
update,
|
|
94
|
+
]);
|
|
95
|
+
};
|
|
96
|
+
//# sourceMappingURL=useHistoriesManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useHistoriesManager.js","sourceRoot":"","sources":["../../../src/business/hooks/useHistoriesManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/business/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/business/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { History } from '@sudobility/mogulgame_types';
|
|
2
|
+
export declare const DEFAULT_CACHE_EXPIRATION_MS: number;
|
|
3
|
+
export interface HistoriesCacheEntry {
|
|
4
|
+
histories: History[];
|
|
5
|
+
cachedAt: number;
|
|
6
|
+
}
|
|
7
|
+
export interface HistoriesStoreState {
|
|
8
|
+
cache: Record<string, HistoriesCacheEntry>;
|
|
9
|
+
setHistories: (userId: string, histories: History[]) => void;
|
|
10
|
+
getHistories: (userId: string, maxAge?: number) => History[] | undefined;
|
|
11
|
+
getCacheEntry: (userId: string, maxAge?: number) => HistoriesCacheEntry | undefined;
|
|
12
|
+
addHistory: (userId: string, history: History) => void;
|
|
13
|
+
updateHistory: (userId: string, historyId: string, history: History) => void;
|
|
14
|
+
removeHistory: (userId: string, historyId: string) => void;
|
|
15
|
+
purgeExpired: (maxAge?: number) => void;
|
|
16
|
+
clearAll: () => void;
|
|
17
|
+
}
|
|
18
|
+
export declare const useHistoriesStore: import("zustand").UseBoundStore<import("zustand").StoreApi<HistoriesStoreState>>;
|
|
19
|
+
//# sourceMappingURL=historiesStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"historiesStore.d.ts","sourceRoot":"","sources":["../../../src/business/stores/historiesStore.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAS3D,eAAO,MAAM,2BAA2B,QAAiB,CAAC;AAQ1D,MAAM,WAAW,mBAAmB;IAElC,SAAS,EAAE,OAAO,EAAE,CAAC;IAErB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAqBD,MAAM,WAAW,mBAAmB;IAElC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IAS3C,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAU7D,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,EAAE,GAAG,SAAS,CAAC;IAUzE,aAAa,EAAE,CACb,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,KACZ,mBAAmB,GAAG,SAAS,CAAC;IASrC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAUvD,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAS7E,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAO3D,YAAY,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAKxC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAqCD,eAAO,MAAM,iBAAiB,kFAwG3B,CAAC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { create } from 'zustand';
|
|
2
|
+
export const DEFAULT_CACHE_EXPIRATION_MS = 10 * 60 * 1000;
|
|
3
|
+
const isCacheExpired = (entry, maxAge) => {
|
|
4
|
+
return Date.now() - entry.cachedAt > maxAge;
|
|
5
|
+
};
|
|
6
|
+
export const useHistoriesStore = create((set, get) => ({
|
|
7
|
+
cache: {},
|
|
8
|
+
setHistories: (userId, histories) => set(state => ({
|
|
9
|
+
cache: {
|
|
10
|
+
...state.cache,
|
|
11
|
+
[userId]: {
|
|
12
|
+
histories,
|
|
13
|
+
cachedAt: Date.now(),
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
})),
|
|
17
|
+
getHistories: (userId, maxAge = DEFAULT_CACHE_EXPIRATION_MS) => {
|
|
18
|
+
const entry = get().cache[userId];
|
|
19
|
+
if (!entry)
|
|
20
|
+
return undefined;
|
|
21
|
+
if (isCacheExpired(entry, maxAge))
|
|
22
|
+
return undefined;
|
|
23
|
+
return entry.histories;
|
|
24
|
+
},
|
|
25
|
+
getCacheEntry: (userId, maxAge = DEFAULT_CACHE_EXPIRATION_MS) => {
|
|
26
|
+
const entry = get().cache[userId];
|
|
27
|
+
if (!entry)
|
|
28
|
+
return undefined;
|
|
29
|
+
if (isCacheExpired(entry, maxAge))
|
|
30
|
+
return undefined;
|
|
31
|
+
return entry;
|
|
32
|
+
},
|
|
33
|
+
addHistory: (userId, history) => set(state => {
|
|
34
|
+
const existing = state.cache[userId];
|
|
35
|
+
if (!existing) {
|
|
36
|
+
return {
|
|
37
|
+
cache: {
|
|
38
|
+
...state.cache,
|
|
39
|
+
[userId]: {
|
|
40
|
+
histories: [history],
|
|
41
|
+
cachedAt: Date.now(),
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
cache: {
|
|
48
|
+
...state.cache,
|
|
49
|
+
[userId]: {
|
|
50
|
+
histories: [...existing.histories, history],
|
|
51
|
+
cachedAt: Date.now(),
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}),
|
|
56
|
+
updateHistory: (userId, historyId, history) => set(state => {
|
|
57
|
+
const existing = state.cache[userId];
|
|
58
|
+
if (!existing)
|
|
59
|
+
return state;
|
|
60
|
+
return {
|
|
61
|
+
cache: {
|
|
62
|
+
...state.cache,
|
|
63
|
+
[userId]: {
|
|
64
|
+
histories: existing.histories.map(h => h.id === historyId ? history : h),
|
|
65
|
+
cachedAt: Date.now(),
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}),
|
|
70
|
+
removeHistory: (userId, historyId) => set(state => {
|
|
71
|
+
const existing = state.cache[userId];
|
|
72
|
+
if (!existing)
|
|
73
|
+
return state;
|
|
74
|
+
return {
|
|
75
|
+
cache: {
|
|
76
|
+
...state.cache,
|
|
77
|
+
[userId]: {
|
|
78
|
+
histories: existing.histories.filter(h => h.id !== historyId),
|
|
79
|
+
cachedAt: Date.now(),
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}),
|
|
84
|
+
purgeExpired: (maxAge = DEFAULT_CACHE_EXPIRATION_MS) => set(state => {
|
|
85
|
+
const now = Date.now();
|
|
86
|
+
const newCache = {};
|
|
87
|
+
for (const [userId, entry] of Object.entries(state.cache)) {
|
|
88
|
+
if (now - entry.cachedAt <= maxAge) {
|
|
89
|
+
newCache[userId] = entry;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return { cache: newCache };
|
|
93
|
+
}),
|
|
94
|
+
clearAll: () => set({ cache: {} }),
|
|
95
|
+
}));
|
|
96
|
+
//# sourceMappingURL=historiesStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"historiesStore.js","sourceRoot":"","sources":["../../../src/business/stores/historiesStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/business/stores/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,2BAA2B,EAC3B,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,GACzB,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/business/stores/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,2BAA2B,GAG5B,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { History } from '@sudobility/mogulgame_types';
|
|
2
|
+
export declare const calculateSum: (histories: History[]) => number;
|
|
3
|
+
export declare const calculatePercentage: (histories: History[], globalTotal: number) => number;
|
|
4
|
+
//# sourceMappingURL=calculations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calculations.d.ts","sourceRoot":"","sources":["../../../src/business/utils/calculations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAiB3D,eAAO,MAAM,YAAY,GAAI,WAAW,OAAO,EAAE,KAAG,MAEnD,CAAC;AA2BF,eAAO,MAAM,mBAAmB,GAC9B,WAAW,OAAO,EAAE,EACpB,aAAa,MAAM,KAClB,MAIF,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const calculateSum = (histories) => {
|
|
2
|
+
return histories.reduce((sum, h) => sum + h.value, 0);
|
|
3
|
+
};
|
|
4
|
+
export const calculatePercentage = (histories, globalTotal) => {
|
|
5
|
+
if (globalTotal <= 0)
|
|
6
|
+
return 0;
|
|
7
|
+
const userSum = calculateSum(histories);
|
|
8
|
+
return (userSum / globalTotal) * 100;
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=calculations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calculations.js","sourceRoot":"","sources":["../../../src/business/utils/calculations.ts"],"names":[],"mappings":"AAiBA,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,SAAoB,EAAU,EAAE;IAC3D,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AACxD,CAAC,CAAC;AA2BF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,SAAoB,EACpB,WAAmB,EACX,EAAE;IACV,IAAI,WAAW,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,OAAO,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IACxC,OAAO,CAAC,OAAO,GAAG,WAAW,CAAC,GAAG,GAAG,CAAC;AACvC,CAAC,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { calculatePercentage, calculateSum } from './calculations';
|
|
2
|
+
export { MAX_OFFER_MULTIPLIER, calculateMaxOffer, validateOfferPrice, calculateBalanceFromLedger, countActiveOffers, countWonOffers, totalActiveOfferValue, formatResolutionSummary, } from './offers';
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/business/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,0BAA0B,EAC1B,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { calculatePercentage, calculateSum } from './calculations';
|
|
2
|
+
export { MAX_OFFER_MULTIPLIER, calculateMaxOffer, validateOfferPrice, calculateBalanceFromLedger, countActiveOffers, countWonOffers, totalActiveOfferValue, formatResolutionSummary, } from './offers';
|
|
3
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/business/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,0BAA0B,EAC1B,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { PretendOffer, PretendOfferResolution, Transaction } from '@sudobility/mogulgame_types';
|
|
2
|
+
export declare const MAX_OFFER_MULTIPLIER = 5;
|
|
3
|
+
export declare const calculateMaxOffer: (balance: number) => number;
|
|
4
|
+
export declare const validateOfferPrice: (offerPrice: number, balance: number) => string | null;
|
|
5
|
+
export declare const calculateBalanceFromLedger: (transactions: Transaction[]) => number;
|
|
6
|
+
export declare const countActiveOffers: (offers: PretendOffer[]) => number;
|
|
7
|
+
export declare const countWonOffers: (offers: PretendOffer[]) => number;
|
|
8
|
+
export declare const totalActiveOfferValue: (offers: PretendOffer[]) => number;
|
|
9
|
+
export declare const formatResolutionSummary: (resolution: PretendOfferResolution) => string;
|
|
10
|
+
//# sourceMappingURL=offers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"offers.d.ts","sourceRoot":"","sources":["../../../src/business/utils/offers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,sBAAsB,EACtB,WAAW,EACZ,MAAM,6BAA6B,CAAC;AAGrC,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAQtC,eAAO,MAAM,iBAAiB,GAAI,SAAS,MAAM,KAAG,MAEnD,CAAC;AASF,eAAO,MAAM,kBAAkB,GAC7B,YAAY,MAAM,EAClB,SAAS,MAAM,KACd,MAAM,GAAG,IASX,CAAC;AAQF,eAAO,MAAM,0BAA0B,GACrC,cAAc,WAAW,EAAE,KAC1B,MAEF,CAAC;AAKF,eAAO,MAAM,iBAAiB,GAAI,QAAQ,YAAY,EAAE,KAAG,MAE1D,CAAC;AAKF,eAAO,MAAM,cAAc,GAAI,QAAQ,YAAY,EAAE,KAAG,MAEvD,CAAC;AAKF,eAAO,MAAM,qBAAqB,GAAI,QAAQ,YAAY,EAAE,KAAG,MAI9D,CAAC;AAKF,eAAO,MAAM,uBAAuB,GAClC,YAAY,sBAAsB,KACjC,MAaF,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export const MAX_OFFER_MULTIPLIER = 5;
|
|
2
|
+
export const calculateMaxOffer = (balance) => {
|
|
3
|
+
return balance * MAX_OFFER_MULTIPLIER;
|
|
4
|
+
};
|
|
5
|
+
export const validateOfferPrice = (offerPrice, balance) => {
|
|
6
|
+
if (offerPrice <= 0) {
|
|
7
|
+
return 'Offer price must be positive';
|
|
8
|
+
}
|
|
9
|
+
const maxOffer = calculateMaxOffer(balance);
|
|
10
|
+
if (offerPrice > maxOffer) {
|
|
11
|
+
return `Offer exceeds maximum allowed ($${maxOffer.toLocaleString()})`;
|
|
12
|
+
}
|
|
13
|
+
return null;
|
|
14
|
+
};
|
|
15
|
+
export const calculateBalanceFromLedger = (transactions) => {
|
|
16
|
+
return transactions.reduce((sum, t) => sum + t.amount, 0);
|
|
17
|
+
};
|
|
18
|
+
export const countActiveOffers = (offers) => {
|
|
19
|
+
return offers.filter(o => o.status === 'active').length;
|
|
20
|
+
};
|
|
21
|
+
export const countWonOffers = (offers) => {
|
|
22
|
+
return offers.filter(o => o.status === 'won').length;
|
|
23
|
+
};
|
|
24
|
+
export const totalActiveOfferValue = (offers) => {
|
|
25
|
+
return offers
|
|
26
|
+
.filter(o => o.status === 'active')
|
|
27
|
+
.reduce((sum, o) => sum + o.offer_price, 0);
|
|
28
|
+
};
|
|
29
|
+
export const formatResolutionSummary = (resolution) => {
|
|
30
|
+
const closingFormatted = `$${resolution.closing_price.toLocaleString()}`;
|
|
31
|
+
const payoutFormatted = `$${resolution.payout_amount.toLocaleString()}`;
|
|
32
|
+
if (!resolution.winner_user_id) {
|
|
33
|
+
return `Property sold for ${closingFormatted}. No qualifying offers.`;
|
|
34
|
+
}
|
|
35
|
+
if (resolution.payout_type === 'solo_bonus') {
|
|
36
|
+
return `Won! Property sold for ${closingFormatted}. Solo bonus: +${payoutFormatted}`;
|
|
37
|
+
}
|
|
38
|
+
return `Won! Property sold for ${closingFormatted}. Payout from competitor: +${payoutFormatted}`;
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=offers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"offers.js","sourceRoot":"","sources":["../../../src/business/utils/offers.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAQtC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,OAAe,EAAU,EAAE;IAC3D,OAAO,OAAO,GAAG,oBAAoB,CAAC;AACxC,CAAC,CAAC;AASF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,UAAkB,EAClB,OAAe,EACA,EAAE;IACjB,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;QACpB,OAAO,8BAA8B,CAAC;IACxC,CAAC;IACD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC5C,IAAI,UAAU,GAAG,QAAQ,EAAE,CAAC;QAC1B,OAAO,mCAAmC,QAAQ,CAAC,cAAc,EAAE,GAAG,CAAC;IACzE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAQF,MAAM,CAAC,MAAM,0BAA0B,GAAG,CACxC,YAA2B,EACnB,EAAE;IACV,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AAC5D,CAAC,CAAC;AAKF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAsB,EAAU,EAAE;IAClE,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,MAAM,CAAC;AAC1D,CAAC,CAAC;AAKF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,MAAsB,EAAU,EAAE;IAC/D,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,MAAM,CAAC;AACvD,CAAC,CAAC;AAKF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,MAAsB,EAAU,EAAE;IACtE,OAAO,MAAM;SACV,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC;SAClC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;AAChD,CAAC,CAAC;AAKF,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACrC,UAAkC,EAC1B,EAAE;IACV,MAAM,gBAAgB,GAAG,IAAI,UAAU,CAAC,aAAa,CAAC,cAAc,EAAE,EAAE,CAAC;IACzE,MAAM,eAAe,GAAG,IAAI,UAAU,CAAC,aAAa,CAAC,cAAc,EAAE,EAAE,CAAC;IAExE,IAAI,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC;QAC/B,OAAO,qBAAqB,gBAAgB,yBAAyB,CAAC;IACxE,CAAC;IAED,IAAI,UAAU,CAAC,WAAW,KAAK,YAAY,EAAE,CAAC;QAC5C,OAAO,0BAA0B,gBAAgB,kBAAkB,eAAe,EAAE,CAAC;IACvF,CAAC;IAED,OAAO,0BAA0B,gBAAgB,8BAA8B,eAAe,EAAE,CAAC;AACnG,CAAC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sudobility/mogulgame_lib",
|
|
3
|
+
"version": "0.0.19",
|
|
4
|
+
"description": "Business logic library for Starter with Zustand stores",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "restricted"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist/**/*"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "bunx tsc -p tsconfig.build.json",
|
|
16
|
+
"build:watch": "bunx tsc --watch",
|
|
17
|
+
"clean": "rm -rf dist",
|
|
18
|
+
"prepublishOnly": "bun run clean && bun run build",
|
|
19
|
+
"typecheck": "bunx tsc --noEmit",
|
|
20
|
+
"lint": "bunx eslint src/",
|
|
21
|
+
"lint:fix": "bunx eslint src/ --fix",
|
|
22
|
+
"format": "bunx prettier --write \"src/**/*.ts\"",
|
|
23
|
+
"format:check": "bunx prettier --check \"src/**/*.ts\"",
|
|
24
|
+
"test": "vitest run",
|
|
25
|
+
"test:watch": "vitest",
|
|
26
|
+
"verify": "bun run typecheck && bun run lint && bun run test && bun run build"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"mogulgame",
|
|
30
|
+
"business-logic",
|
|
31
|
+
"zustand",
|
|
32
|
+
"react",
|
|
33
|
+
"typescript"
|
|
34
|
+
],
|
|
35
|
+
"author": "Sudobility",
|
|
36
|
+
"license": "BUSL-1.1",
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"@sudobility/types": "^1.9.61",
|
|
39
|
+
"@tanstack/react-query": ">=5.0.0",
|
|
40
|
+
"react": ">=18.0.0",
|
|
41
|
+
"zustand": ">=5.0.0"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@eslint/js": "^9.38.0",
|
|
45
|
+
"@sudobility/mogulgame_client": "^0.0.21",
|
|
46
|
+
"@sudobility/mogulgame_types": "^0.0.14",
|
|
47
|
+
"@sudobility/types": "^1.9.61",
|
|
48
|
+
"@tanstack/react-query": "^5.90.5",
|
|
49
|
+
"@testing-library/react": "^16.3.2",
|
|
50
|
+
"@testing-library/react-hooks": "^8.0.1",
|
|
51
|
+
"@types/react": "^19.2.2",
|
|
52
|
+
"@typescript-eslint/eslint-plugin": "^8.46.2",
|
|
53
|
+
"@typescript-eslint/parser": "^8.46.2",
|
|
54
|
+
"eslint": "^9.39.2",
|
|
55
|
+
"eslint-config-prettier": "^10.1.5",
|
|
56
|
+
"eslint-plugin-prettier": "^5.4.1",
|
|
57
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
|
58
|
+
"globals": "^16.4.0",
|
|
59
|
+
"jsdom": "^28.1.0",
|
|
60
|
+
"prettier": "^3.7.4",
|
|
61
|
+
"react": "^19.2.1",
|
|
62
|
+
"react-dom": "^19.2.4",
|
|
63
|
+
"typescript": "~5.9.3",
|
|
64
|
+
"vitest": "^4.0.15",
|
|
65
|
+
"zustand": "^5.0.8"
|
|
66
|
+
},
|
|
67
|
+
"repository": {
|
|
68
|
+
"type": "git",
|
|
69
|
+
"url": "https://github.com/sudobility-usf/starter_lib.git"
|
|
70
|
+
}
|
|
71
|
+
}
|