orionplace-react 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.
- package/LICENSE +21 -0
- package/README.md +242 -0
- package/bin/orionplace-react.mjs +101 -0
- package/package.json +56 -0
- package/runtime/marketplace.d.mts +22 -0
- package/runtime/marketplace.mjs +211 -0
- package/src/project-readme.mjs +341 -0
- package/src/setup.mjs +250 -0
- package/src/update.mjs +36 -0
- package/src/validation.mjs +27 -0
- package/templates/app/api/[...orionplace]/route.ts +14 -0
- package/templates/app/globals.css +10 -0
- package/templates/app/layout.tsx +25 -0
- package/templates/app/page.module.css +133 -0
- package/templates/app/page.tsx +80 -0
- package/templates/hooks/useOrionplaceAppLoad.ts +34 -0
- package/templates/interfaces/orionplace/apiBase/TMethod.ts +1 -0
- package/templates/interfaces/orionplace/appBase/IAppLoad.ts +15 -0
- package/templates/interfaces/orionplace/appBase/IAppLoadCommon.ts +54 -0
- package/templates/interfaces/orionplace/appBase/IApploadUserProfile.ts +13 -0
- package/templates/interfaces/orionplace/appBase/IForm.ts +21 -0
- package/templates/interfaces/orionplace/appBase/ISEO.ts +21 -0
- package/templates/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonBanner.ts +11 -0
- package/templates/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonContact.ts +8 -0
- package/templates/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonCurrency.ts +15 -0
- package/templates/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonEvents.ts +18 -0
- package/templates/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonLocale.ts +14 -0
- package/templates/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonLogos.ts +6 -0
- package/templates/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonPath.ts +22 -0
- package/templates/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonSEO.ts +13 -0
- package/templates/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonSocial.ts +15 -0
- package/templates/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonTariff.ts +7 -0
- package/templates/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonUnit.ts +12 -0
- package/templates/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonVariables.ts +7 -0
- package/templates/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonVisualSettings.ts +11 -0
- package/templates/interfaces/orionplace/appBase/appLoadCommon/IAppLoadCommonWalletValue.ts +3 -0
- package/templates/interfaces/orionplace/category/ICategory.ts +40 -0
- package/templates/interfaces/orionplace/domains/IDomain.ts +13 -0
- package/templates/interfaces/orionplace/index.ts +30 -0
- package/templates/interfaces/orionplace/products/IProduct.ts +235 -0
- package/templates/interfaces/orionplace/shared/IGeoCoordinates.ts +4 -0
- package/templates/interfaces/orionplace/shared/ITransformValue.ts +3 -0
- package/templates/interfaces/orionplace/state.ts +4 -0
- package/templates/interfaces/orionplace/subscribeOptions/ISubscribeOption.ts +9 -0
- package/templates/interfaces/orionplace/subscribeTariff/ISubscribeTariff.ts +46 -0
- package/templates/interfaces/orionplace/subscribes/ISubscribe.ts +28 -0
- package/templates/interfaces/orionplace/transport.ts +30 -0
- package/templates/lib/orionplace/appLoadClient.ts +33 -0
- package/templates/lib/orionplace/appLoadResult.ts +56 -0
- package/templates/lib/orionplace/appLoadServer.ts +72 -0
- package/templates/lib/orionplace/domain.ts +16 -0
- package/templates/providers/OrionplaceProvider.tsx +39 -0
- package/templates/proxy.ts +17 -0
- package/templates/stores/orionplace.ts +119 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { createStore } from 'zustand/vanilla';
|
|
2
|
+
import type {
|
|
3
|
+
AppLoadFailure, AppLoadLoader, AppLoadResult, AppLoadStatus,
|
|
4
|
+
IAppLoad, IAppLoadCommon, IAppLoadCommonCurrency, IAppLoadCommonLocale, IAppLoadCommonTariff,
|
|
5
|
+
IAppLoadPath, IAppLoadPathObject, IApploadUserProfile, ICategory, IProduct,
|
|
6
|
+
} from '../interfaces/orionplace';
|
|
7
|
+
import { appLoadFailure } from '../lib/orionplace/appLoadResult';
|
|
8
|
+
|
|
9
|
+
/** Shared empty values keep selector results referentially stable between renders. */
|
|
10
|
+
const EMPTY_RECORD = Object.freeze({}) as Record<string, never>;
|
|
11
|
+
const EMPTY_LIST = Object.freeze([]) as readonly never[];
|
|
12
|
+
const EMPTY_PATHS = Object.freeze({}) as IAppLoadPathObject;
|
|
13
|
+
|
|
14
|
+
export interface OrionplaceSnapshot {
|
|
15
|
+
result: AppLoadResult | null;
|
|
16
|
+
status: AppLoadStatus;
|
|
17
|
+
failure: AppLoadFailure | null;
|
|
18
|
+
endpoints: IAppLoadPathObject;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface OrionplaceState extends OrionplaceSnapshot {
|
|
22
|
+
load: (loader: AppLoadLoader, force?: boolean) => Promise<void>;
|
|
23
|
+
reset: () => void;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type OrionplaceStore = ReturnType<typeof createOrionplaceStore>;
|
|
27
|
+
|
|
28
|
+
/** Public and authenticated discovery are merged once per snapshot, without mutating the response. */
|
|
29
|
+
function mergeEndpoints(result: AppLoadResult | null): IAppLoadPathObject {
|
|
30
|
+
const page = result?.response.page_data;
|
|
31
|
+
if (!page) return EMPTY_PATHS;
|
|
32
|
+
const groups: IAppLoadPathObject[] = [page.unauth.paths];
|
|
33
|
+
if (page.init.is_authenticated && page.auth) groups.push(page.auth.paths);
|
|
34
|
+
const merged: IAppLoadPathObject = {};
|
|
35
|
+
for (const group of groups) {
|
|
36
|
+
for (const [section, paths] of Object.entries(group)) merged[section] = { ...merged[section], ...paths };
|
|
37
|
+
}
|
|
38
|
+
return merged;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Builds the hydration snapshot from a server render, without repeating the request. */
|
|
42
|
+
export function initialSnapshot(
|
|
43
|
+
result: AppLoadResult | null = null,
|
|
44
|
+
failure: AppLoadFailure | null = null,
|
|
45
|
+
): OrionplaceSnapshot {
|
|
46
|
+
return {
|
|
47
|
+
result: failure ? null : result,
|
|
48
|
+
status: failure ? 'error' : result ? 'success' : 'idle',
|
|
49
|
+
failure,
|
|
50
|
+
endpoints: failure ? EMPTY_PATHS : mergeEndpoints(result),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* One store instance per server render and one per browser session.
|
|
56
|
+
* Creating the store never starts a request; the loaders are passed to `load`.
|
|
57
|
+
*/
|
|
58
|
+
export function createOrionplaceStore(snapshot: OrionplaceSnapshot = initialSnapshot()) {
|
|
59
|
+
// These belong to this store instance, never serialized state or a module-level cache.
|
|
60
|
+
let pending: Promise<void> | null = null;
|
|
61
|
+
let controller: AbortController | null = null;
|
|
62
|
+
let generation = 0;
|
|
63
|
+
|
|
64
|
+
return createStore<OrionplaceState>()((set, get) => ({
|
|
65
|
+
...snapshot,
|
|
66
|
+
|
|
67
|
+
reset() {
|
|
68
|
+
generation++;
|
|
69
|
+
controller?.abort();
|
|
70
|
+
controller = null;
|
|
71
|
+
pending = null;
|
|
72
|
+
set({ result: null, failure: null, status: 'idle', endpoints: EMPTY_PATHS });
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
load(loader: AppLoadLoader, force = false): Promise<void> {
|
|
76
|
+
if (pending) return pending;
|
|
77
|
+
// Reuse both server success and failure after hydration or navigation; retry is explicit.
|
|
78
|
+
if (!force && get().status !== 'idle') return Promise.resolve();
|
|
79
|
+
const current = ++generation;
|
|
80
|
+
controller = new AbortController();
|
|
81
|
+
const signal = controller.signal;
|
|
82
|
+
set({ result: null, failure: null, status: 'pending', endpoints: EMPTY_PATHS });
|
|
83
|
+
pending = Promise.resolve().then(() => loader(signal)).then(result => {
|
|
84
|
+
if (current !== generation) return;
|
|
85
|
+
set({ result, status: 'success', endpoints: mergeEndpoints(result) });
|
|
86
|
+
}).catch((error: unknown) => {
|
|
87
|
+
if (current !== generation) return;
|
|
88
|
+
set({ failure: appLoadFailure(error), status: 'error' });
|
|
89
|
+
}).finally(() => {
|
|
90
|
+
if (current !== generation) return;
|
|
91
|
+
pending = null;
|
|
92
|
+
controller = null;
|
|
93
|
+
});
|
|
94
|
+
return pending;
|
|
95
|
+
},
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export const selectIsReady = (state: OrionplaceSnapshot): boolean => state.status === 'success' && state.result !== null;
|
|
100
|
+
export const selectStatus = (state: OrionplaceSnapshot): AppLoadStatus => state.status;
|
|
101
|
+
export const selectFailure = (state: OrionplaceSnapshot): AppLoadFailure | null => state.failure;
|
|
102
|
+
export const selectResult = (state: OrionplaceSnapshot): AppLoadResult | null => state.result;
|
|
103
|
+
export const selectData = (state: OrionplaceSnapshot): IAppLoad | null => state.result?.response.page_data ?? null;
|
|
104
|
+
export const selectInit = (state: OrionplaceSnapshot): IAppLoadCommon | null => selectData(state)?.init ?? null;
|
|
105
|
+
export const selectProfile = (state: OrionplaceSnapshot): IApploadUserProfile | null => selectData(state)?.user ?? null;
|
|
106
|
+
export const selectIsAuthenticated = (state: OrionplaceSnapshot): boolean => selectInit(state)?.is_authenticated ?? false;
|
|
107
|
+
export const selectLocales = (state: OrionplaceSnapshot): Record<string, IAppLoadCommonLocale> => selectInit(state)?.locale ?? EMPTY_RECORD;
|
|
108
|
+
export const selectCurrencies = (state: OrionplaceSnapshot): Record<string, IAppLoadCommonCurrency> => selectInit(state)?.currencies ?? EMPTY_RECORD;
|
|
109
|
+
export const selectCatalog = (state: OrionplaceSnapshot): readonly ICategory[] => selectInit(state)?.catalog ?? EMPTY_LIST;
|
|
110
|
+
export const selectProducts = (state: OrionplaceSnapshot): readonly IProduct[] => selectInit(state)?.products ?? EMPTY_LIST;
|
|
111
|
+
export const selectTariffs = (state: OrionplaceSnapshot): IAppLoadCommonTariff | null => selectInit(state)?.tariffs ?? null;
|
|
112
|
+
export const selectPublicEndpoints = (state: OrionplaceSnapshot): IAppLoadPathObject => selectData(state)?.unauth.paths ?? EMPTY_PATHS;
|
|
113
|
+
export const selectEndpoints = (state: OrionplaceSnapshot): IAppLoadPathObject => state.endpoints;
|
|
114
|
+
export const selectAuthenticatedEndpoints = (state: OrionplaceSnapshot): IAppLoadPathObject =>
|
|
115
|
+
selectIsAuthenticated(state) ? selectData(state)?.auth?.paths ?? EMPTY_PATHS : EMPTY_PATHS;
|
|
116
|
+
|
|
117
|
+
/** Live discovery describes availability; the backend still checks permissions on every call. */
|
|
118
|
+
export const selectEndpoint = (section: string, name: string) =>
|
|
119
|
+
(state: OrionplaceSnapshot): IAppLoadPath | undefined => state.endpoints[section]?.[name];
|