@sincpro/mobile 0.4.3 → 0.4.4
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/dist/adapters/ReceiptExporter.adapter.js +10 -2
- package/dist/entrypoints/ui/common_provider.d.ts +1 -1
- package/dist/entrypoints/ui/common_provider.js +2 -2
- package/dist/entrypoints/ui/domain_switcher.d.ts +2 -2
- package/dist/framework/feature.d.ts +26 -0
- package/dist/framework/feature.js +36 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/infrastructure/interceptor/intercept.d.ts +7 -2
- package/dist/infrastructure/interceptor/intercept.js +5 -2
- package/dist/infrastructure/telemetry/tracing/tracing_hooks.d.ts +9 -6
- package/dist/infrastructure/telemetry/tracing/tracing_hooks.js +60 -37
- package/dist/ui/components/atoms/DebugBanner.d.ts +1 -1
- package/dist/ui/components/molecules/BluetoothDeviceSelectorModal.d.ts +1 -1
- package/dist/ui/components/molecules/BluetoothDeviceSelectorModal.js +8 -2
- package/dist/ui/components/molecules/DeadLetterErrorBlock.d.ts +1 -1
- package/dist/ui/components/molecules/EventTimelineItem.d.ts +1 -1
- package/dist/ui/components/molecules/GeoPermissionCard.d.ts +1 -1
- package/dist/ui/components/molecules/ProcessToastProvider.d.ts +1 -1
- package/dist/ui/components/molecules/TimeZoneSelector.d.ts +1 -1
- package/dist/ui/components/molecules/TimeZoneSelectorModal.d.ts +1 -1
- package/dist/ui/components/molecules/TimeZoneSelectorModal.js +5 -3
- package/dist/ui/components/organisms/BluetoothPrinterSelector.d.ts +1 -1
- package/dist/ui/components/organisms/BluetoothPrinterSelector.js +3 -0
- package/dist/ui/components/organisms/DatabaseInfoRow.d.ts +1 -1
- package/dist/ui/components/organisms/DeadLetterQueueRow.d.ts +2 -1
- package/dist/ui/components/organisms/EventRow.d.ts +1 -1
- package/dist/ui/components/organisms/InjectableWebView.d.ts +2 -2
- package/dist/ui/components/organisms/InjectableWebView.js +6 -3
- package/dist/ui/components/organisms/Receipt.d.ts +2 -1
- package/dist/ui/components/organisms/TableInfoInfoRow.d.ts +1 -1
- package/dist/ui/screens/database/database.context.d.ts +2 -2
- package/dist/ui/screens/database/database.context.js +9 -18
- package/dist/ui/screens/database/database.json_detail.d.ts +1 -1
- package/dist/ui/screens/database/database.list.d.ts +1 -1
- package/dist/ui/screens/database/database.table_rows.d.ts +1 -1
- package/dist/ui/screens/dead_letter_queue/dead_letter_queue.context.d.ts +2 -2
- package/dist/ui/screens/dead_letter_queue/dead_letter_queue.list.d.ts +1 -1
- package/dist/ui/screens/events/events.context.d.ts +2 -2
- package/dist/ui/screens/events/events.context.js +20 -25
- package/dist/ui/screens/events/events.list.d.ts +1 -1
- package/package.json +41 -35
|
@@ -3,6 +3,14 @@ import * as Sharing from "expo-sharing";
|
|
|
3
3
|
import { PDFDocument } from "pdf-lib";
|
|
4
4
|
import { Platform } from "react-native";
|
|
5
5
|
import { captureRef } from "react-native-view-shot";
|
|
6
|
+
/**
|
|
7
|
+
* view-shot 6 types a target as a class instance or a host node. React Native
|
|
8
|
+
* 0.88 types `View` as a function, so the ref we already hold is the same
|
|
9
|
+
* object at runtime and a different type here.
|
|
10
|
+
*/
|
|
11
|
+
function shotTarget(viewRef) {
|
|
12
|
+
return viewRef;
|
|
13
|
+
}
|
|
6
14
|
const DEFAULT_CONFIG = {
|
|
7
15
|
RECEIPT_WIDTH_MM: 72,
|
|
8
16
|
MM_TO_POINTS: 2.83464567,
|
|
@@ -16,7 +24,7 @@ function generateFileName(baseName, extension = "pdf") {
|
|
|
16
24
|
return `${sanitized}_${Date.now()}.${extension}`;
|
|
17
25
|
}
|
|
18
26
|
async function captureViewToTmpFile(viewRef, quality) {
|
|
19
|
-
const tmpUri = await captureRef(viewRef, {
|
|
27
|
+
const tmpUri = await captureRef(shotTarget(viewRef), {
|
|
20
28
|
format: "jpg",
|
|
21
29
|
quality,
|
|
22
30
|
result: "tmpfile",
|
|
@@ -67,7 +75,7 @@ async function captureViewToBase64(viewRef, quality) {
|
|
|
67
75
|
if (!viewRef.current)
|
|
68
76
|
return null;
|
|
69
77
|
try {
|
|
70
|
-
const base64 = await captureRef(viewRef, {
|
|
78
|
+
const base64 = await captureRef(shotTarget(viewRef), {
|
|
71
79
|
format: "png",
|
|
72
80
|
quality,
|
|
73
81
|
result: "base64",
|
|
@@ -36,6 +36,6 @@ interface CommonProviderProps {
|
|
|
36
36
|
lightTheme?: ThemeTokens;
|
|
37
37
|
darkTheme?: ThemeTokens;
|
|
38
38
|
}
|
|
39
|
-
export declare function CommonProvider({ children, lightTheme, darkTheme }: CommonProviderProps): import("react
|
|
39
|
+
export declare function CommonProvider({ children, lightTheme, darkTheme }: CommonProviderProps): import("react").JSX.Element;
|
|
40
40
|
export declare function useCommon(): ICommonContext;
|
|
41
41
|
export {};
|
|
@@ -104,10 +104,10 @@ export function CommonProvider({ children, lightTheme, darkTheme }) {
|
|
|
104
104
|
applyTheme(scheme);
|
|
105
105
|
}, [applyTheme]);
|
|
106
106
|
useEffect(() => {
|
|
107
|
-
checkGeoPermission();
|
|
107
|
+
Promise.resolve().then(() => checkGeoPermission());
|
|
108
108
|
const sub = AppState.addEventListener("change", (state) => {
|
|
109
109
|
if (state === "active")
|
|
110
|
-
checkGeoPermission();
|
|
110
|
+
Promise.resolve().then(() => checkGeoPermission());
|
|
111
111
|
});
|
|
112
112
|
return () => sub.remove();
|
|
113
113
|
}, [checkGeoPermission]);
|
|
@@ -13,7 +13,7 @@ export declare function DomainSwitcherProvider(props: {
|
|
|
13
13
|
apps: DomainApp[];
|
|
14
14
|
initialDomain: string;
|
|
15
15
|
children: ReactNode;
|
|
16
|
-
}): import("react
|
|
16
|
+
}): import("react").JSX.Element;
|
|
17
17
|
export declare function useDomainSwitcher(): DomainSwitcherValue;
|
|
18
|
-
export declare function ActiveDomainApp(): import("react
|
|
18
|
+
export declare function ActiveDomainApp(): import("react").JSX.Element | null;
|
|
19
19
|
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One operation. What the context injects (a repository, an adapter) is `deps`,
|
|
3
|
+
* typed by the subclass.
|
|
4
|
+
*
|
|
5
|
+
* `new` returns a proxy: every public method of the subclass runs inside a span
|
|
6
|
+
* named `ClassName.method`. A name that starts with `_` does not. The author
|
|
7
|
+
* does not open a span. If tracing is not initialized, or the exporter fails,
|
|
8
|
+
* the method still runs.
|
|
9
|
+
*
|
|
10
|
+
* A subclass constructor calls `super(deps)` and does not return another object.
|
|
11
|
+
*/
|
|
12
|
+
export declare class Feature<Deps extends object = Record<string, never>> {
|
|
13
|
+
protected readonly deps: Deps;
|
|
14
|
+
constructor(deps?: Deps);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Composes the `Feature`s of its own context. `features` is that set, and only
|
|
18
|
+
* that set: another context's feature is not on the type.
|
|
19
|
+
*
|
|
20
|
+
* `run` is the parent span. Each `this.features.*` call in that turn is a child
|
|
21
|
+
* of the same trace. It does not call another `ApplicationService`.
|
|
22
|
+
*/
|
|
23
|
+
export declare class ApplicationService<TFeatures extends Record<string, Feature<Record<string, unknown>>>, Deps extends object = Record<string, never>> extends Feature<Deps> {
|
|
24
|
+
protected readonly features: TFeatures;
|
|
25
|
+
constructor(features: TFeatures, deps?: Deps);
|
|
26
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { interceptInstance } from "../infrastructure/interceptor/intercept";
|
|
2
|
+
import { tracingHooks } from "../infrastructure/telemetry/tracing/tracing_hooks";
|
|
3
|
+
/**
|
|
4
|
+
* One operation. What the context injects (a repository, an adapter) is `deps`,
|
|
5
|
+
* typed by the subclass.
|
|
6
|
+
*
|
|
7
|
+
* `new` returns a proxy: every public method of the subclass runs inside a span
|
|
8
|
+
* named `ClassName.method`. A name that starts with `_` does not. The author
|
|
9
|
+
* does not open a span. If tracing is not initialized, or the exporter fails,
|
|
10
|
+
* the method still runs.
|
|
11
|
+
*
|
|
12
|
+
* A subclass constructor calls `super(deps)` and does not return another object.
|
|
13
|
+
*/
|
|
14
|
+
export class Feature {
|
|
15
|
+
deps;
|
|
16
|
+
constructor(deps) {
|
|
17
|
+
this.deps = deps ?? {};
|
|
18
|
+
return interceptInstance(this, tracingHooks(new.target.name), {
|
|
19
|
+
skip: (methodName) => methodName.startsWith("_"),
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Composes the `Feature`s of its own context. `features` is that set, and only
|
|
25
|
+
* that set: another context's feature is not on the type.
|
|
26
|
+
*
|
|
27
|
+
* `run` is the parent span. Each `this.features.*` call in that turn is a child
|
|
28
|
+
* of the same trace. It does not call another `ApplicationService`.
|
|
29
|
+
*/
|
|
30
|
+
export class ApplicationService extends Feature {
|
|
31
|
+
features;
|
|
32
|
+
constructor(features, deps) {
|
|
33
|
+
super(deps);
|
|
34
|
+
this.features = features;
|
|
35
|
+
}
|
|
36
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export { BaseModule, baseModule } from "./framework/base_module";
|
|
|
11
11
|
export type { AppConfig } from "./framework/createApp";
|
|
12
12
|
export { createApp } from "./framework/createApp";
|
|
13
13
|
export { DomainModule } from "./framework/domain_module";
|
|
14
|
+
export { ApplicationService, Feature } from "./framework/feature";
|
|
14
15
|
export { Kernel } from "./framework/kernel";
|
|
15
16
|
export { orchestrator } from "./framework/orchestrator";
|
|
16
17
|
export { installGlobalErrorHandler } from "./infrastructure/ui/errorHandler";
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export { createTheme } from "./entrypoints/ui/theme";
|
|
|
6
6
|
export { BaseModule, baseModule } from "./framework/base_module";
|
|
7
7
|
export { createApp } from "./framework/createApp";
|
|
8
8
|
export { DomainModule } from "./framework/domain_module";
|
|
9
|
+
export { ApplicationService, Feature } from "./framework/feature";
|
|
9
10
|
export { Kernel } from "./framework/kernel";
|
|
10
11
|
export { orchestrator } from "./framework/orchestrator";
|
|
11
12
|
export { installGlobalErrorHandler } from "./infrastructure/ui/errorHandler";
|
|
@@ -41,6 +41,10 @@ export declare function interceptClass<T extends new (...args: never[]) => objec
|
|
|
41
41
|
* function's `.name` (or `"anonymous"` if unnamed).
|
|
42
42
|
*/
|
|
43
43
|
export declare function interceptFunction<T extends (...args: never[]) => unknown>(fn: T, hooks: InterceptorHooks): T;
|
|
44
|
+
export type InstanceInterceptOptions = {
|
|
45
|
+
/** Method names for which the proxy returns the raw function. */
|
|
46
|
+
skip?: (methodName: string) => boolean;
|
|
47
|
+
};
|
|
44
48
|
/**
|
|
45
49
|
* Wraps a single live instance via Proxy without touching the class prototype.
|
|
46
50
|
* Use for singletons exported directly (e.g. `dbCursor`, `distributionWorkflows`).
|
|
@@ -52,6 +56,7 @@ export declare function interceptFunction<T extends (...args: never[]) => unknow
|
|
|
52
56
|
*
|
|
53
57
|
* Hooks contract: `before` fires before the call; `after` fires on success with
|
|
54
58
|
* the resolved value; `onError` fires on throw or rejection — the error is always
|
|
55
|
-
* re-thrown after `onError` completes.
|
|
59
|
+
* re-thrown after `onError` completes. `skip` leaves a method unwrapped — a `_`
|
|
60
|
+
* helper must not open a span.
|
|
56
61
|
*/
|
|
57
|
-
export declare function interceptInstance<T extends object>(instance: T, hooks: InterceptorHooks): T;
|
|
62
|
+
export declare function interceptInstance<T extends object>(instance: T, hooks: InterceptorHooks, options?: InstanceInterceptOptions): T;
|
|
@@ -96,9 +96,10 @@ export function interceptFunction(fn, hooks) {
|
|
|
96
96
|
*
|
|
97
97
|
* Hooks contract: `before` fires before the call; `after` fires on success with
|
|
98
98
|
* the resolved value; `onError` fires on throw or rejection — the error is always
|
|
99
|
-
* re-thrown after `onError` completes.
|
|
99
|
+
* re-thrown after `onError` completes. `skip` leaves a method unwrapped — a `_`
|
|
100
|
+
* helper must not open a span.
|
|
100
101
|
*/
|
|
101
|
-
export function interceptInstance(instance, hooks) {
|
|
102
|
+
export function interceptInstance(instance, hooks, options) {
|
|
102
103
|
const className = instance.constructor?.name ?? "Object";
|
|
103
104
|
return new Proxy(instance, {
|
|
104
105
|
get(target, prop, receiver) {
|
|
@@ -106,6 +107,8 @@ export function interceptInstance(instance, hooks) {
|
|
|
106
107
|
if (typeof value !== "function" || typeof prop === "symbol") {
|
|
107
108
|
return value;
|
|
108
109
|
}
|
|
110
|
+
if (options?.skip?.(prop))
|
|
111
|
+
return value;
|
|
109
112
|
return wrap(value, className, prop, hooks).bind(target);
|
|
110
113
|
},
|
|
111
114
|
});
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import type { InterceptorHooks } from "
|
|
1
|
+
import type { InterceptorHooks } from "../../../infrastructure/interceptor/intercept";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* value inside our Context, pushed in `before` and popped in `after`/`onError`.
|
|
3
|
+
* A span per intercepted call. The active span lives in the framework context,
|
|
4
|
+
* so a nested call — an application service running a feature — is a child of
|
|
5
|
+
* the same trace.
|
|
7
6
|
*
|
|
8
|
-
*
|
|
7
|
+
* Tracing is optional. No provider, a missing SDK, or an exporter that throws:
|
|
8
|
+
* the hooks swallow it and the use case runs. `before` only records a push it
|
|
9
|
+
* actually made, so `after` never pops a context it did not push.
|
|
10
|
+
*
|
|
11
|
+
* @param tracerName - instrumentation scope, e.g. "sincpro.mobile.checkout"
|
|
9
12
|
*/
|
|
10
13
|
export declare function tracingHooks(tracerName: string): InterceptorHooks;
|
|
@@ -1,59 +1,82 @@
|
|
|
1
1
|
import { ROOT_CONTEXT as OTEL_ROOT, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
2
|
-
import { _getContextManager } from "
|
|
3
|
-
import { OTEL_CTX_KEY } from "
|
|
2
|
+
import { _getContextManager } from "../../../infrastructure/context_manager";
|
|
3
|
+
import { OTEL_CTX_KEY } from "../../../infrastructure/telemetry/context_keys";
|
|
4
4
|
const _spanMap = new WeakMap();
|
|
5
5
|
// Tracks whether `before` successfully pushed a context entry for this call.
|
|
6
6
|
// Guards `after`/`onError` against popping a context they never pushed.
|
|
7
7
|
const _pushedMap = new WeakSet();
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* value inside our Context, pushed in `before` and popped in `after`/`onError`.
|
|
9
|
+
* A span per intercepted call. The active span lives in the framework context,
|
|
10
|
+
* so a nested call — an application service running a feature — is a child of
|
|
11
|
+
* the same trace.
|
|
13
12
|
*
|
|
14
|
-
*
|
|
13
|
+
* Tracing is optional. No provider, a missing SDK, or an exporter that throws:
|
|
14
|
+
* the hooks swallow it and the use case runs. `before` only records a push it
|
|
15
|
+
* actually made, so `after` never pops a context it did not push.
|
|
16
|
+
*
|
|
17
|
+
* @param tracerName - instrumentation scope, e.g. "sincpro.mobile.checkout"
|
|
15
18
|
*/
|
|
16
19
|
export function tracingHooks(tracerName) {
|
|
17
20
|
return {
|
|
18
21
|
before(call) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
_pushedMap.add(call);
|
|
22
|
+
try {
|
|
23
|
+
const manager = _getContextManager();
|
|
24
|
+
const frameworkCtx = manager.active();
|
|
25
|
+
const otelCtx = frameworkCtx.get(OTEL_CTX_KEY) ?? OTEL_ROOT;
|
|
26
|
+
const spanName = call.className
|
|
27
|
+
? `${call.className}.${call.methodName}`
|
|
28
|
+
: call.methodName;
|
|
29
|
+
const span = trace.getTracer(tracerName).startSpan(spanName, undefined, otelCtx);
|
|
30
|
+
_spanMap.set(call, span);
|
|
31
|
+
manager.push(frameworkCtx.set(OTEL_CTX_KEY, trace.setSpan(otelCtx, span)));
|
|
32
|
+
_pushedMap.add(call);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
_spanMap.delete(call);
|
|
36
|
+
}
|
|
35
37
|
},
|
|
36
38
|
after(call) {
|
|
37
39
|
const span = _spanMap.get(call);
|
|
38
|
-
if (!span)
|
|
39
|
-
return;
|
|
40
40
|
_spanMap.delete(call);
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
try {
|
|
42
|
+
span?.setStatus({ code: SpanStatusCode.OK });
|
|
43
|
+
span?.end();
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// The use case already finished. A failing exporter does not change that.
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
pop(call);
|
|
50
|
+
}
|
|
45
51
|
},
|
|
46
52
|
onError(call, error) {
|
|
47
53
|
const span = _spanMap.get(call);
|
|
48
|
-
if (!span)
|
|
49
|
-
return;
|
|
50
54
|
_spanMap.delete(call);
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
try {
|
|
56
|
+
if (error instanceof Error)
|
|
57
|
+
span?.recordException(error);
|
|
58
|
+
span?.setStatus({
|
|
59
|
+
code: SpanStatusCode.ERROR,
|
|
60
|
+
message: error instanceof Error ? error.message : undefined,
|
|
61
|
+
});
|
|
62
|
+
span?.end();
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// Same as `after`: the business error is the one that propagates.
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
pop(call);
|
|
69
|
+
}
|
|
57
70
|
},
|
|
58
71
|
};
|
|
59
72
|
}
|
|
73
|
+
function pop(call) {
|
|
74
|
+
if (!_pushedMap.delete(call))
|
|
75
|
+
return;
|
|
76
|
+
try {
|
|
77
|
+
_getContextManager().pop();
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// The stack was already cleared. Nothing of this call is left on it.
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare function DebugBanner(): import("react
|
|
1
|
+
declare function DebugBanner(): import("react").JSX.Element | null;
|
|
2
2
|
export { DebugBanner };
|
|
@@ -4,5 +4,5 @@ interface BluetoothDeviceSelectorModalProps {
|
|
|
4
4
|
onClose: () => void;
|
|
5
5
|
onSelect: (device: BluetoothDevice) => void;
|
|
6
6
|
}
|
|
7
|
-
declare function BluetoothDeviceSelectorModal({ visible, onClose, onSelect, }: BluetoothDeviceSelectorModalProps): import("react
|
|
7
|
+
declare function BluetoothDeviceSelectorModal({ visible, onClose, onSelect, }: BluetoothDeviceSelectorModalProps): import("react").JSX.Element;
|
|
8
8
|
export { BluetoothDeviceSelectorModal };
|
|
@@ -23,6 +23,13 @@ function BluetoothDeviceSelectorModal({ visible, onClose, onSelect, }) {
|
|
|
23
23
|
const [loading, setLoading] = useState(false);
|
|
24
24
|
const [selectedDevice, setSelectedDevice] = useState(null);
|
|
25
25
|
const [connecting, setConnecting] = useState(false);
|
|
26
|
+
const [prevVisible, setPrevVisible] = useState(visible);
|
|
27
|
+
if (visible !== prevVisible) {
|
|
28
|
+
setPrevVisible(visible);
|
|
29
|
+
if (visible) {
|
|
30
|
+
setSelectedDevice(null);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
26
33
|
const loadDevices = useCallback(async () => {
|
|
27
34
|
setLoading(true);
|
|
28
35
|
try {
|
|
@@ -38,8 +45,7 @@ function BluetoothDeviceSelectorModal({ visible, onClose, onSelect, }) {
|
|
|
38
45
|
}, []);
|
|
39
46
|
useEffect(() => {
|
|
40
47
|
if (visible) {
|
|
41
|
-
loadDevices();
|
|
42
|
-
setSelectedDevice(null);
|
|
48
|
+
Promise.resolve().then(() => loadDevices());
|
|
43
49
|
}
|
|
44
50
|
}, [visible, loadDevices]);
|
|
45
51
|
async function handleConfirm() {
|
|
@@ -4,5 +4,5 @@ interface DeadLetterErrorBlockProps {
|
|
|
4
4
|
onToggle: () => void;
|
|
5
5
|
previewChars?: number;
|
|
6
6
|
}
|
|
7
|
-
declare function DeadLetterErrorBlock({ errorMessage, expanded, onToggle, previewChars, }: DeadLetterErrorBlockProps): import("react
|
|
7
|
+
declare function DeadLetterErrorBlock({ errorMessage, expanded, onToggle, previewChars, }: DeadLetterErrorBlockProps): import("react").JSX.Element | null;
|
|
8
8
|
export default DeadLetterErrorBlock;
|
|
@@ -3,5 +3,5 @@ interface EventTimelineItemProps {
|
|
|
3
3
|
event: DomainEvent;
|
|
4
4
|
isLast?: boolean;
|
|
5
5
|
}
|
|
6
|
-
declare function EventTimelineItem({ event, isLast }: EventTimelineItemProps): import("react
|
|
6
|
+
declare function EventTimelineItem({ event, isLast }: EventTimelineItemProps): import("react").JSX.Element;
|
|
7
7
|
export default EventTimelineItem;
|
|
@@ -4,5 +4,5 @@ interface GeoPermissionCardProps {
|
|
|
4
4
|
loading?: boolean;
|
|
5
5
|
handleRequestPermission?: () => void;
|
|
6
6
|
}
|
|
7
|
-
declare function GeoPermissionCard({ title, loading, handleRequestPermission, hasPermission, }: GeoPermissionCardProps): import("react
|
|
7
|
+
declare function GeoPermissionCard({ title, loading, handleRequestPermission, hasPermission, }: GeoPermissionCardProps): import("react").JSX.Element;
|
|
8
8
|
export default GeoPermissionCard;
|
|
@@ -3,5 +3,5 @@ interface TimeZoneSelectorProps {
|
|
|
3
3
|
onSelect?: (tz: TimezoneLocale) => void;
|
|
4
4
|
timezone?: string | null;
|
|
5
5
|
}
|
|
6
|
-
export declare function TimeZoneSelector({ onSelect, timezone }: TimeZoneSelectorProps): import("react
|
|
6
|
+
export declare function TimeZoneSelector({ onSelect, timezone }: TimeZoneSelectorProps): import("react").JSX.Element;
|
|
7
7
|
export {};
|
|
@@ -5,5 +5,5 @@ interface TimeZoneSelectorModalProps {
|
|
|
5
5
|
onSelect: (tz: TimezoneLocale) => void;
|
|
6
6
|
currentTimezone?: string | null;
|
|
7
7
|
}
|
|
8
|
-
declare function TimeZoneSelectorModal({ visible, onClose, onSelect, currentTimezone, }: TimeZoneSelectorModalProps): import("react
|
|
8
|
+
declare function TimeZoneSelectorModal({ visible, onClose, onSelect, currentTimezone, }: TimeZoneSelectorModalProps): import("react").JSX.Element;
|
|
9
9
|
export { TimeZoneSelectorModal };
|
|
@@ -4,7 +4,7 @@ import { Display } from "@sincpro/mobile-ui/Display";
|
|
|
4
4
|
import { Form } from "@sincpro/mobile-ui/Form";
|
|
5
5
|
import { useTheme } from "@sincpro/mobile-ui/theme";
|
|
6
6
|
import { Typography } from "@sincpro/mobile-ui/Typography";
|
|
7
|
-
import {
|
|
7
|
+
import { useMemo, useState } from "react";
|
|
8
8
|
import { TextInput, TouchableOpacity, View } from "react-native";
|
|
9
9
|
const TIMEZONES_LOCALES = {
|
|
10
10
|
bolivia: { timezone: "America/La_Paz", locale: "es-BO" },
|
|
@@ -27,12 +27,14 @@ function TimeZoneSelectorModal({ visible, onClose, onSelect, currentTimezone, })
|
|
|
27
27
|
const theme = useTheme();
|
|
28
28
|
const [query, setQuery] = useState("");
|
|
29
29
|
const [selectedTimezone, setSelectedTimezone] = useState(currentTimezone || null);
|
|
30
|
-
|
|
30
|
+
const [prevVisible, setPrevVisible] = useState(visible);
|
|
31
|
+
if (visible !== prevVisible) {
|
|
32
|
+
setPrevVisible(visible);
|
|
31
33
|
if (visible) {
|
|
32
34
|
setQuery("");
|
|
33
35
|
setSelectedTimezone(currentTimezone || null);
|
|
34
36
|
}
|
|
35
|
-
}
|
|
37
|
+
}
|
|
36
38
|
const timezoneList = useMemo(() => {
|
|
37
39
|
return Object.values(TIMEZONES_LOCALES).map((tz) => ({
|
|
38
40
|
...tz,
|
|
@@ -5,5 +5,5 @@ interface BluetoothPrinterSelectorProps {
|
|
|
5
5
|
/** Render as section rows (no outer card) — use inside FormViewV2.Content.Section. */
|
|
6
6
|
compact?: boolean;
|
|
7
7
|
}
|
|
8
|
-
declare function BluetoothPrinterSelector({ onPrinterSelected, onConnectionChange, compact, }: BluetoothPrinterSelectorProps): import("react
|
|
8
|
+
declare function BluetoothPrinterSelector({ onPrinterSelected, onConnectionChange, compact, }: BluetoothPrinterSelectorProps): import("react").JSX.Element;
|
|
9
9
|
export { BluetoothPrinterSelector };
|
|
@@ -43,6 +43,9 @@ function BluetoothPrinterSelector({ onPrinterSelected, onConnectionChange, compa
|
|
|
43
43
|
setIsConnected(connected);
|
|
44
44
|
}, []);
|
|
45
45
|
useEffect(() => {
|
|
46
|
+
// Async side effect on mount — checkStatus does sync setState internally,
|
|
47
|
+
// which is the documented React 19 pattern for on-mount async work.
|
|
48
|
+
// eslint-disable-next-line react-hooks/set-state-in-effect
|
|
46
49
|
checkStatus();
|
|
47
50
|
}, [checkStatus]);
|
|
48
51
|
useEffect(() => {
|
|
@@ -7,5 +7,5 @@ interface DatabaseInfoRowProps {
|
|
|
7
7
|
item: DatabaseInfoRowData;
|
|
8
8
|
onPress?: () => void;
|
|
9
9
|
}
|
|
10
|
-
declare function DatabaseInfoRow({ item, onPress }: DatabaseInfoRowProps): import("react
|
|
10
|
+
declare function DatabaseInfoRow({ item, onPress }: DatabaseInfoRowProps): import("react").JSX.Element;
|
|
11
11
|
export default DatabaseInfoRow;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { DomainEvent } from "../../../domain/event_sourcing";
|
|
2
2
|
import { IRowItemProps } from "@sincpro/mobile-ui/views/types/IListView";
|
|
3
|
+
import React from "react";
|
|
3
4
|
interface DeadLetterQueueRowProps extends IRowItemProps<DomainEvent> {
|
|
4
5
|
onRetry: (event: DomainEvent) => Promise<void> | void;
|
|
5
6
|
}
|
|
6
|
-
declare function DeadLetterQueueRow({ item, onRetry }: DeadLetterQueueRowProps):
|
|
7
|
+
declare function DeadLetterQueueRow({ item, onRetry }: DeadLetterQueueRowProps): React.JSX.Element | null;
|
|
7
8
|
export default DeadLetterQueueRow;
|
|
@@ -3,5 +3,5 @@ interface EventRowProps {
|
|
|
3
3
|
item: DomainEvent;
|
|
4
4
|
onRetry: (event: DomainEvent) => Promise<void> | void;
|
|
5
5
|
}
|
|
6
|
-
declare function EventRow({ item, onRetry }: EventRowProps): import("react
|
|
6
|
+
declare function EventRow({ item, onRetry }: EventRowProps): import("react").JSX.Element | null;
|
|
7
7
|
export default EventRow;
|
|
@@ -27,8 +27,8 @@ interface WebViewControlsProps {
|
|
|
27
27
|
onGoForward: () => void;
|
|
28
28
|
onReload: () => void;
|
|
29
29
|
}
|
|
30
|
-
declare function WebViewControls({ canGoBack: _canGoBack, canGoForward: _canGoForward, onGoBack: _onGoBack, onGoForward: _onGoForward, onReload: _onReload, }: WebViewControlsProps): import("react
|
|
31
|
-
declare function InjectableWebView({ url, scripts, injectedJavaScript, onMessage, onNavigationChange, onLoadStart, onLoadEnd, onError, renderLoading, backgroundColor, reloadKey, hardRefreshKey, maxRetries, useDefaultCache, }: InjectableWebViewProps): import("react
|
|
30
|
+
declare function WebViewControls({ canGoBack: _canGoBack, canGoForward: _canGoForward, onGoBack: _onGoBack, onGoForward: _onGoForward, onReload: _onReload, }: WebViewControlsProps): import("react").JSX.Element;
|
|
31
|
+
declare function InjectableWebView({ url, scripts, injectedJavaScript, onMessage, onNavigationChange, onLoadStart, onLoadEnd, onError, renderLoading, backgroundColor, reloadKey, hardRefreshKey, maxRetries, useDefaultCache, }: InjectableWebViewProps): import("react").JSX.Element;
|
|
32
32
|
declare namespace InjectableWebView {
|
|
33
33
|
var Controls: typeof WebViewControls;
|
|
34
34
|
}
|
|
@@ -4,15 +4,18 @@ import { webViewService } from "../../../services/webview.service";
|
|
|
4
4
|
import { useToast } from "@sincpro/mobile-ui/Feedback";
|
|
5
5
|
import Spinner from "@sincpro/mobile-ui/Feedback/Feedback.Spinner";
|
|
6
6
|
import { useBottomInset } from "@sincpro/mobile-ui/layouts/BottomInset";
|
|
7
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
7
|
+
import { useCallback, useEffect, useRef, useState, } from "react";
|
|
8
8
|
import { BackHandler, StyleSheet, View } from "react-native";
|
|
9
9
|
import { SafeAreaView } from "react-native-safe-area-context";
|
|
10
|
-
import
|
|
10
|
+
import RawWebView from "react-native-webview";
|
|
11
|
+
// The library defaults its extra-props generic to `undefined`, and
|
|
12
|
+
// `WebViewProps & undefined` collapses to `never`. An empty record keeps the real props.
|
|
13
|
+
const WebView = RawWebView;
|
|
11
14
|
function WebViewControls({ canGoBack: _canGoBack, canGoForward: _canGoForward, onGoBack: _onGoBack, onGoForward: _onGoForward, onReload: _onReload, }) {
|
|
12
15
|
return _jsx(View, {});
|
|
13
16
|
}
|
|
14
17
|
function WebViewLoadingIndicator({ backgroundColor }) {
|
|
15
|
-
return (_jsx(View, { style: [StyleSheet.
|
|
18
|
+
return (_jsx(View, { style: [StyleSheet.absoluteFill, styles.loading, { backgroundColor }], children: _jsx(Spinner, { size: "large", text: "Cargando p\u00E1gina..." }) }));
|
|
16
19
|
}
|
|
17
20
|
function useWebView() {
|
|
18
21
|
const toast = useToast();
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { FormatterMap, LabelMap } from "../../../domain/receipt";
|
|
2
|
+
import React from "react";
|
|
2
3
|
interface ReceiptProps {
|
|
3
4
|
data: Record<string, any>;
|
|
4
5
|
labels?: LabelMap;
|
|
@@ -7,5 +8,5 @@ interface ReceiptProps {
|
|
|
7
8
|
formatters?: FormatterMap;
|
|
8
9
|
emptyPlaceholder?: string;
|
|
9
10
|
}
|
|
10
|
-
declare function Receipt({ data, labels, order, strictOrder, formatters, emptyPlaceholder, }: ReceiptProps):
|
|
11
|
+
declare function Receipt({ data, labels, order, strictOrder, formatters, emptyPlaceholder, }: ReceiptProps): React.JSX.Element;
|
|
11
12
|
export default Receipt;
|
|
@@ -5,5 +5,5 @@ interface TableListItemProps {
|
|
|
5
5
|
item: TableRowData;
|
|
6
6
|
onPress?: () => void;
|
|
7
7
|
}
|
|
8
|
-
declare function TableInfoRow({ item, onPress }: TableListItemProps): import("react
|
|
8
|
+
declare function TableInfoRow({ item, onPress }: TableListItemProps): import("react").JSX.Element;
|
|
9
9
|
export default TableInfoRow;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReactNode } from "react";
|
|
1
|
+
import React, { ReactNode } from "react";
|
|
2
2
|
export declare enum EDatabaseView {
|
|
3
3
|
TABLES_LIST = "TABLES_LIST",
|
|
4
4
|
TABLE_ROWS = "TABLE_ROWS",
|
|
@@ -27,6 +27,6 @@ interface IDatabaseContext {
|
|
|
27
27
|
}
|
|
28
28
|
export declare function DatabaseProvider({ children }: {
|
|
29
29
|
children: ReactNode;
|
|
30
|
-
}):
|
|
30
|
+
}): React.JSX.Element;
|
|
31
31
|
export declare function useDatabase(): IDatabaseContext;
|
|
32
32
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "nativewind/jsx-runtime";
|
|
2
2
|
import { databaseTablesUseCase } from "../../../services/database_table.service";
|
|
3
3
|
import { safeJsonParse, safeJsonStringify } from "../../../tools/utils/serializer";
|
|
4
|
-
import { createContext, useCallback, useContext,
|
|
4
|
+
import { createContext, useCallback, useContext, useMemo, useState, } from "react";
|
|
5
5
|
export var EDatabaseView;
|
|
6
6
|
(function (EDatabaseView) {
|
|
7
7
|
EDatabaseView["TABLES_LIST"] = "TABLES_LIST";
|
|
@@ -13,7 +13,6 @@ export function DatabaseProvider({ children }) {
|
|
|
13
13
|
const [currentView, setCurrentView] = useState(EDatabaseView.TABLES_LIST);
|
|
14
14
|
const [tables, setTables] = useState([]);
|
|
15
15
|
const [data, setData] = useState([]);
|
|
16
|
-
const [filteredData, setFilteredData] = useState([]);
|
|
17
16
|
const [isLoading, setIsLoading] = useState(false);
|
|
18
17
|
const [selectedTable, setSelectedTable] = useState("");
|
|
19
18
|
const [selectedRowJson, setSelectedRowJson] = useState("");
|
|
@@ -21,13 +20,11 @@ export function DatabaseProvider({ children }) {
|
|
|
21
20
|
const [currentRowIndex, setCurrentRowIndex] = useState(0);
|
|
22
21
|
const [previousSearchQuery, setPreviousSearchQuery] = useState("");
|
|
23
22
|
const [isTransitioning, setIsTransitioning] = useState(false);
|
|
24
|
-
const
|
|
25
|
-
if (!searchQuery.trim())
|
|
26
|
-
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
23
|
+
const filteredData = useMemo(() => {
|
|
24
|
+
if (!searchQuery.trim())
|
|
25
|
+
return data;
|
|
29
26
|
const query = searchQuery.toLowerCase().trim();
|
|
30
|
-
|
|
27
|
+
return data.filter((row) => {
|
|
31
28
|
const parsedData = safeJsonParse(typeof row === "string" ? row : JSON.stringify(row));
|
|
32
29
|
if (!parsedData)
|
|
33
30
|
return false;
|
|
@@ -36,11 +33,7 @@ export function DatabaseProvider({ children }) {
|
|
|
36
33
|
const name = parsedData.name?.toLowerCase() || "";
|
|
37
34
|
return remoteId.includes(query) || uuid.includes(query) || name.includes(query);
|
|
38
35
|
});
|
|
39
|
-
setFilteredData(filtered);
|
|
40
36
|
}, [data, searchQuery]);
|
|
41
|
-
useEffect(() => {
|
|
42
|
-
filterData();
|
|
43
|
-
}, [filterData]);
|
|
44
37
|
const loadTables = useCallback(async () => {
|
|
45
38
|
setIsLoading(true);
|
|
46
39
|
try {
|
|
@@ -121,12 +114,10 @@ export function DatabaseProvider({ children }) {
|
|
|
121
114
|
}, [currentRowIndex, filteredData, isTransitioning]);
|
|
122
115
|
const hasNextRow = currentRowIndex < filteredData.length - 1;
|
|
123
116
|
const hasPreviousRow = currentRowIndex > 0;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
}, [searchQuery, previousSearchQuery, currentView, goBackFromJson]);
|
|
117
|
+
if (currentView === EDatabaseView.JSON_DETAIL && searchQuery !== previousSearchQuery) {
|
|
118
|
+
setPreviousSearchQuery(searchQuery);
|
|
119
|
+
goBackFromJson();
|
|
120
|
+
}
|
|
130
121
|
return (_jsx(DatabaseContext.Provider, { value: {
|
|
131
122
|
currentView,
|
|
132
123
|
tables,
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare function JsonDetailView(): import("react
|
|
1
|
+
declare function JsonDetailView(): import("react").JSX.Element;
|
|
2
2
|
export default JsonDetailView;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export default function DatabaseList(): import("react
|
|
1
|
+
export default function DatabaseList(): import("react").JSX.Element;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare function TableRowsView(): import("react
|
|
1
|
+
declare function TableRowsView(): import("react").JSX.Element;
|
|
2
2
|
export default TableRowsView;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DomainEvent } from "../../../domain/event_sourcing";
|
|
2
|
-
import { ReactNode } from "react";
|
|
2
|
+
import React, { ReactNode } from "react";
|
|
3
3
|
interface IDeadLetterQueueContext {
|
|
4
4
|
events: DomainEvent[];
|
|
5
5
|
enrichedEvents: DomainEvent[];
|
|
@@ -29,6 +29,6 @@ interface IDeadLetterQueueContext {
|
|
|
29
29
|
}
|
|
30
30
|
export declare function DeadLetterQueueProvider({ children }: {
|
|
31
31
|
children: ReactNode;
|
|
32
|
-
}):
|
|
32
|
+
}): React.JSX.Element;
|
|
33
33
|
export declare function useDeadLetterQueue(): IDeadLetterQueueContext;
|
|
34
34
|
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare function DeadLetterQueueList(): import("react
|
|
1
|
+
declare function DeadLetterQueueList(): import("react").JSX.Element;
|
|
2
2
|
export default DeadLetterQueueList;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DomainEvent } from "../../../domain/event_sourcing";
|
|
2
|
-
import { ReactNode } from "react";
|
|
2
|
+
import React, { ReactNode } from "react";
|
|
3
3
|
type EventFilter = "ALL" | "FAILED" | "ACKNOWLEDGED" | "PENDING";
|
|
4
4
|
interface IEventsContext {
|
|
5
5
|
events: DomainEvent[];
|
|
@@ -20,6 +20,6 @@ interface IEventsContext {
|
|
|
20
20
|
export declare function EventsProvider({ children, pageSize, }: {
|
|
21
21
|
children: ReactNode;
|
|
22
22
|
pageSize?: number;
|
|
23
|
-
}):
|
|
23
|
+
}): React.JSX.Element;
|
|
24
24
|
export declare function useEvents(): IEventsContext;
|
|
25
25
|
export {};
|
|
@@ -1,66 +1,61 @@
|
|
|
1
1
|
import { jsx as _jsx } from "nativewind/jsx-runtime";
|
|
2
2
|
import { eventService } from "../../../services/event.service";
|
|
3
|
-
import { createContext, useCallback, useContext,
|
|
3
|
+
import { createContext, useCallback, useContext, useMemo, useState, } from "react";
|
|
4
4
|
const EventsContext = createContext(null);
|
|
5
5
|
export function EventsProvider({ children, pageSize = 25, }) {
|
|
6
6
|
const [events, setEvents] = useState([]);
|
|
7
|
-
const [pagedEvents, setPagedEvents] = useState([]);
|
|
8
7
|
const [isLoading, setIsLoading] = useState(false);
|
|
9
8
|
const [isLoadingMore, setIsLoadingMore] = useState(false);
|
|
10
9
|
const [isRetrying, setIsRetrying] = useState(false);
|
|
11
10
|
const [page, setPage] = useState(1);
|
|
12
|
-
const [hasMore, setHasMore] = useState(false);
|
|
13
11
|
const [filter, setFilter] = useState("ALL");
|
|
14
|
-
const
|
|
15
|
-
if (
|
|
16
|
-
return
|
|
17
|
-
return
|
|
12
|
+
const filteredEvents = useMemo(() => {
|
|
13
|
+
if (filter === "ALL")
|
|
14
|
+
return events;
|
|
15
|
+
return events.filter((ev) => {
|
|
18
16
|
if (!ev.status)
|
|
19
17
|
return false;
|
|
20
|
-
if (
|
|
18
|
+
if (filter === "FAILED")
|
|
21
19
|
return ev.status === "FAILED";
|
|
22
|
-
if (
|
|
20
|
+
if (filter === "ACKNOWLEDGED")
|
|
23
21
|
return ev.status === "ACKNOWLEDGED";
|
|
24
|
-
if (
|
|
22
|
+
if (filter === "PENDING")
|
|
25
23
|
return ev.status === "PENDING";
|
|
26
24
|
return true;
|
|
27
25
|
});
|
|
28
|
-
}, []);
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
setPage(
|
|
35
|
-
}
|
|
26
|
+
}, [events, filter]);
|
|
27
|
+
const pagedEvents = useMemo(() => filteredEvents.slice(0, page * pageSize), [filteredEvents, page, pageSize]);
|
|
28
|
+
const hasMore = pagedEvents.length < filteredEvents.length;
|
|
29
|
+
const [prevFilter, setPrevFilter] = useState(filter);
|
|
30
|
+
if (filter !== prevFilter) {
|
|
31
|
+
setPrevFilter(filter);
|
|
32
|
+
setPage(1);
|
|
33
|
+
}
|
|
36
34
|
const loadEvents = useCallback(async () => {
|
|
37
35
|
setIsLoading(true);
|
|
38
36
|
try {
|
|
39
37
|
const fetched = await eventService.listAllEvents();
|
|
40
38
|
setEvents(fetched);
|
|
41
|
-
|
|
39
|
+
setPage(1);
|
|
42
40
|
}
|
|
43
41
|
finally {
|
|
44
42
|
setIsLoading(false);
|
|
45
43
|
}
|
|
46
|
-
}, [
|
|
44
|
+
}, []);
|
|
47
45
|
const refreshEvents = useCallback(async () => {
|
|
48
46
|
await loadEvents();
|
|
49
47
|
}, [loadEvents]);
|
|
50
|
-
useEffect(() => {
|
|
51
|
-
paginate(events, 1, filter);
|
|
52
|
-
}, [events, filter, paginate]);
|
|
53
48
|
const loadMore = useCallback(async () => {
|
|
54
49
|
if (isLoadingMore || isLoading || !hasMore)
|
|
55
50
|
return;
|
|
56
51
|
setIsLoadingMore(true);
|
|
57
52
|
try {
|
|
58
|
-
|
|
53
|
+
setPage((p) => p + 1);
|
|
59
54
|
}
|
|
60
55
|
finally {
|
|
61
56
|
setIsLoadingMore(false);
|
|
62
57
|
}
|
|
63
|
-
}, [
|
|
58
|
+
}, [hasMore, isLoading, isLoadingMore]);
|
|
64
59
|
const retryEvent = useCallback(async (event) => {
|
|
65
60
|
setIsRetrying(true);
|
|
66
61
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export default function EventsScreen(): import("react
|
|
1
|
+
export default function EventsScreen(): import("react").JSX.Element;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sincpro/mobile",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"description": "Sincpro Mobile framework core: offline-first infra (DB, queue/events, cron), DDD patterns, adapters, AppShell and module-driven composition for React Native",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -26,18 +26,21 @@
|
|
|
26
26
|
"repository": "https://github.com/Sincpro-SRL/sincpro_mobile",
|
|
27
27
|
"author": "Gutierrez, Andres <andres.gutierrez@sincpro.com.bo>",
|
|
28
28
|
"license": "MIT",
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=26"
|
|
31
|
+
},
|
|
29
32
|
"dependencies": {
|
|
30
|
-
"@opentelemetry/api": "^1.9.
|
|
31
|
-
"@opentelemetry/core": "^2.
|
|
32
|
-
"@opentelemetry/resources": "^2.
|
|
33
|
-
"@opentelemetry/sdk-trace-base": "^2.
|
|
33
|
+
"@opentelemetry/api": "^1.9.1",
|
|
34
|
+
"@opentelemetry/core": "^2.10.0",
|
|
35
|
+
"@opentelemetry/resources": "^2.10.0",
|
|
36
|
+
"@opentelemetry/sdk-trace-base": "^2.10.0",
|
|
34
37
|
"async-mutex": "^0.5.0",
|
|
35
38
|
"big.js": "^7.0.1",
|
|
36
|
-
"dayjs": "^1.11.
|
|
39
|
+
"dayjs": "^1.11.21",
|
|
37
40
|
"mitt": "^3.0.1",
|
|
38
41
|
"pdf-lib": "^1.17.1",
|
|
39
42
|
"tailwind-variants": "^3.2.2",
|
|
40
|
-
"uuid": "^
|
|
43
|
+
"uuid": "^14.0.1"
|
|
41
44
|
},
|
|
42
45
|
"peerDependencies": {
|
|
43
46
|
"@react-navigation/native": ">=7",
|
|
@@ -56,7 +59,7 @@
|
|
|
56
59
|
"expo-splash-screen": "*",
|
|
57
60
|
"expo-sqlite": "*",
|
|
58
61
|
"expo-task-manager": "*",
|
|
59
|
-
"nativewind": ">=4",
|
|
62
|
+
"nativewind": ">=4.2.7",
|
|
60
63
|
"react": "*",
|
|
61
64
|
"react-native": "*",
|
|
62
65
|
"react-native-gesture-handler": "*",
|
|
@@ -65,7 +68,8 @@
|
|
|
65
68
|
"react-native-screens": "*",
|
|
66
69
|
"react-native-toast-message": "*",
|
|
67
70
|
"react-native-view-shot": "*",
|
|
68
|
-
"react-native-webview": "*"
|
|
71
|
+
"react-native-webview": "*",
|
|
72
|
+
"react-native-worklets": "*"
|
|
69
73
|
},
|
|
70
74
|
"devDependencies": {
|
|
71
75
|
"@opentelemetry/api": "^1.9.0",
|
|
@@ -73,40 +77,42 @@
|
|
|
73
77
|
"@react-navigation/native-stack": "^7.0.0",
|
|
74
78
|
"@sincpro/mobile-ui": "^0.7.2",
|
|
75
79
|
"@types/big.js": "^6.2.2",
|
|
76
|
-
"@types/react": "~19.
|
|
80
|
+
"@types/react": "~19.3.0",
|
|
77
81
|
"@types/uuid": "^10.0.0",
|
|
78
82
|
"eslint": "^9.35.0",
|
|
79
|
-
"eslint-config-expo": "~
|
|
83
|
+
"eslint-config-expo": "~58.0.4",
|
|
80
84
|
"eslint-config-prettier": "^10.1.8",
|
|
81
85
|
"eslint-plugin-prettier": "^5.5.4",
|
|
82
86
|
"eslint-plugin-react": "^7.37.2",
|
|
83
87
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
84
|
-
"expo-background-task": "~
|
|
85
|
-
"expo-clipboard": "~
|
|
86
|
-
"expo-crypto": "~
|
|
87
|
-
"expo-file-system": "~
|
|
88
|
-
"expo-linking": "~
|
|
89
|
-
"expo-localization": "~
|
|
90
|
-
"expo-location": "~
|
|
91
|
-
"expo-network": "~
|
|
92
|
-
"expo-print": "~
|
|
93
|
-
"expo-sharing": "~
|
|
94
|
-
"expo-splash-screen": "~
|
|
95
|
-
"expo-sqlite": "~
|
|
96
|
-
"expo-task-manager": "~
|
|
97
|
-
"nativewind": "
|
|
88
|
+
"expo-background-task": "~58.0.12",
|
|
89
|
+
"expo-clipboard": "~58.0.4",
|
|
90
|
+
"expo-crypto": "~58.0.7",
|
|
91
|
+
"expo-file-system": "~58.0.13",
|
|
92
|
+
"expo-linking": "~58.0.16",
|
|
93
|
+
"expo-localization": "~58.0.5",
|
|
94
|
+
"expo-location": "~58.0.20",
|
|
95
|
+
"expo-network": "~58.0.4",
|
|
96
|
+
"expo-print": "~58.0.8",
|
|
97
|
+
"expo-sharing": "~58.0.22",
|
|
98
|
+
"expo-splash-screen": "~58.0.13",
|
|
99
|
+
"expo-sqlite": "~58.0.15",
|
|
100
|
+
"expo-task-manager": "~58.0.13",
|
|
101
|
+
"nativewind": "4.2.7",
|
|
102
|
+
"tailwindcss": "3.4.19",
|
|
98
103
|
"prettier": "^3.6.2",
|
|
99
|
-
"react": "19.
|
|
100
|
-
"react-native": "0.
|
|
101
|
-
"react-native-gesture-handler": "~
|
|
102
|
-
"react-native-keyboard-controller": "1.
|
|
103
|
-
"react-native-reanimated": "
|
|
104
|
-
"react-native-safe-area-context": "~5.
|
|
105
|
-
"react-native-screens": "~4.
|
|
106
|
-
"react-native-svg": "15.
|
|
104
|
+
"react": "19.3.0",
|
|
105
|
+
"react-native": "0.88.1",
|
|
106
|
+
"react-native-gesture-handler": "~3.3.0",
|
|
107
|
+
"react-native-keyboard-controller": "1.22.7",
|
|
108
|
+
"react-native-reanimated": "4.7.1",
|
|
109
|
+
"react-native-safe-area-context": "~5.11.1",
|
|
110
|
+
"react-native-screens": "~4.30.1",
|
|
111
|
+
"react-native-svg": "15.16.0",
|
|
107
112
|
"react-native-toast-message": "^2.3.3",
|
|
108
|
-
"react-native-view-shot": "
|
|
109
|
-
"react-native-webview": "
|
|
113
|
+
"react-native-view-shot": "6.1.1",
|
|
114
|
+
"react-native-webview": "14.0.1",
|
|
115
|
+
"react-native-worklets": "0.13.0",
|
|
110
116
|
"tsc-alias": "^1.8.17",
|
|
111
117
|
"tsx": "^4.22.4",
|
|
112
118
|
"typescript": "~5.9.2"
|