@koolbase/react-native 9.2.0 → 10.0.1
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/CHANGELOG.md +1348 -0
- package/README.md +403 -568
- package/dist/{auth-storage.d.ts → cjs/auth-storage.d.ts} +1 -1
- package/dist/cjs/index.d.ts +19 -0
- package/dist/cjs/index.js +125 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/platform.d.ts +2 -0
- package/dist/cjs/platform.js +43 -0
- package/dist/esm/auth-storage.d.ts +26 -0
- package/dist/esm/auth-storage.js +100 -0
- package/dist/esm/index.d.ts +19 -0
- package/dist/esm/index.js +106 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/platform.d.ts +2 -0
- package/dist/esm/platform.js +37 -0
- package/package.json +30 -30
- package/dist/analytics.d.ts +0 -24
- package/dist/analytics.js +0 -114
- package/dist/apple-auth.d.ts +0 -22
- package/dist/apple-auth.js +0 -74
- package/dist/auth-errors.d.ts +0 -117
- package/dist/auth-errors.js +0 -250
- package/dist/auth.d.ts +0 -213
- package/dist/auth.js +0 -810
- package/dist/cache-store.d.ts +0 -50
- package/dist/cache-store.js +0 -197
- package/dist/code-push.d.ts +0 -59
- package/dist/code-push.js +0 -255
- package/dist/conflict.d.ts +0 -80
- package/dist/conflict.js +0 -84
- package/dist/database-errors.d.ts +0 -101
- package/dist/database-errors.js +0 -200
- package/dist/database.d.ts +0 -298
- package/dist/database.js +0 -852
- package/dist/device-id.d.ts +0 -1
- package/dist/device-id.js +0 -60
- package/dist/device-metadata.d.ts +0 -36
- package/dist/device-metadata.js +0 -102
- package/dist/errors.d.ts +0 -64
- package/dist/errors.js +0 -85
- package/dist/flags.d.ts +0 -15
- package/dist/flags.js +0 -76
- package/dist/function-errors.d.ts +0 -51
- package/dist/function-errors.js +0 -103
- package/dist/functions.d.ts +0 -15
- package/dist/functions.js +0 -83
- package/dist/index.d.ts +0 -49
- package/dist/index.js +0 -204
- package/dist/logic-engine.d.ts +0 -17
- package/dist/logic-engine.js +0 -193
- package/dist/messaging.d.ts +0 -13
- package/dist/messaging.js +0 -36
- package/dist/offline-state.d.ts +0 -97
- package/dist/offline-state.js +0 -200
- package/dist/pending-write.d.ts +0 -47
- package/dist/pending-write.js +0 -22
- package/dist/realtime.d.ts +0 -44
- package/dist/realtime.js +0 -195
- package/dist/record.d.ts +0 -2
- package/dist/record.js +0 -23
- package/dist/storage-errors.d.ts +0 -163
- package/dist/storage-errors.js +0 -253
- package/dist/storage.d.ts +0 -198
- package/dist/storage.js +0 -451
- package/dist/sync-engine.d.ts +0 -30
- package/dist/sync-engine.js +0 -290
- package/dist/types.d.ts +0 -487
- package/dist/types.js +0 -40
- /package/dist/{auth-storage.js → cjs/auth-storage.js} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { KoolbaseAuthStorage, KoolbaseSession } from '
|
|
1
|
+
import type { KoolbaseAuthStorage, KoolbaseSession } from '@koolbase/core';
|
|
2
2
|
/**
|
|
3
3
|
* Probe whether react-native-keychain is installed without throwing.
|
|
4
4
|
* Used by KoolbaseAuth to decide whether to instantiate a default
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export * from '@koolbase/core';
|
|
2
|
+
export { reactNativePlatform } from './platform.js';
|
|
3
|
+
import { KoolbaseAuth, KoolbaseDatabase, KoolbaseStorage, KoolbaseRealtime, KoolbaseFunctions, KoolbaseAnalytics, KoolbaseMessaging, type KoolbaseConfig, type VersionCheckResult } from '@koolbase/core';
|
|
4
|
+
export declare const Koolbase: {
|
|
5
|
+
initialize(config: KoolbaseConfig): Promise<void>;
|
|
6
|
+
readonly auth: KoolbaseAuth;
|
|
7
|
+
readonly db: KoolbaseDatabase;
|
|
8
|
+
readonly storage: KoolbaseStorage;
|
|
9
|
+
readonly realtime: KoolbaseRealtime;
|
|
10
|
+
readonly functions: KoolbaseFunctions;
|
|
11
|
+
isEnabled(key: string): boolean;
|
|
12
|
+
configString(key: string, fallback?: string): string;
|
|
13
|
+
configNumber(key: string, fallback?: number): number;
|
|
14
|
+
configBool(key: string, fallback?: boolean): boolean;
|
|
15
|
+
readonly analytics: KoolbaseAnalytics;
|
|
16
|
+
readonly messaging: KoolbaseMessaging;
|
|
17
|
+
checkVersion(currentVersion: string): VersionCheckResult;
|
|
18
|
+
};
|
|
19
|
+
export { SecureAuthStorage } from './auth-storage.js';
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// @koolbase/react-native — composes @koolbase/core for a React Native host.
|
|
3
|
+
//
|
|
4
|
+
// Everything the core exports is re-exported here unchanged, so an app that
|
|
5
|
+
// installed this package before the split sees the same surface. What this
|
|
6
|
+
// file adds is the composition: one Koolbase singleton, initialized with the
|
|
7
|
+
// React Native platform adapter and keychain-backed session storage.
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
20
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.SecureAuthStorage = exports.Koolbase = exports.reactNativePlatform = void 0;
|
|
24
|
+
__exportStar(require("@koolbase/core"), exports);
|
|
25
|
+
var platform_js_1 = require("./platform.js");
|
|
26
|
+
Object.defineProperty(exports, "reactNativePlatform", { enumerable: true, get: function () { return platform_js_1.reactNativePlatform; } });
|
|
27
|
+
const core_1 = require("@koolbase/core");
|
|
28
|
+
const platform_js_2 = require("./platform.js");
|
|
29
|
+
let _auth = null;
|
|
30
|
+
let _db = null;
|
|
31
|
+
let _storage = null;
|
|
32
|
+
let _realtime = null;
|
|
33
|
+
let _functions = null;
|
|
34
|
+
let _flags = null;
|
|
35
|
+
let _analytics = null;
|
|
36
|
+
let _messaging = null;
|
|
37
|
+
let _initialized = false;
|
|
38
|
+
function ensureInitialized() {
|
|
39
|
+
if (!_initialized) {
|
|
40
|
+
throw new Error('Koolbase not initialized. Call Koolbase.initialize() first.');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.Koolbase = {
|
|
44
|
+
async initialize(config) {
|
|
45
|
+
if (_initialized)
|
|
46
|
+
return;
|
|
47
|
+
// The host platform, installed before any subsystem touches storage or
|
|
48
|
+
// the network. Tests leave this unset and run on the in-memory default.
|
|
49
|
+
(0, core_1.setPlatform)(config.platform ?? (0, platform_js_2.reactNativePlatform)());
|
|
50
|
+
_auth = new core_1.KoolbaseAuth(config);
|
|
51
|
+
_db = new core_1.KoolbaseDatabase(config, () => _auth?.currentUser?.id ?? null, () => _auth?.validAccessToken() ?? Promise.resolve(null),
|
|
52
|
+
// A session the server refuses is not a session. Clearing it here means an
|
|
53
|
+
// app catching KoolbaseUnauthenticatedError is already signed out and can
|
|
54
|
+
// route to login, rather than looping on a dead token.
|
|
55
|
+
async () => { await _auth?.clearStoredSession(); });
|
|
56
|
+
_storage = new core_1.KoolbaseStorage(config, () => _auth?.validAccessToken() ?? Promise.resolve(null), async () => { await _auth?.clearStoredSession(); });
|
|
57
|
+
_realtime = new core_1.KoolbaseRealtime(config, () => _auth?.validAccessToken() ?? Promise.resolve(null), () => _auth?.currentUser?.id ?? null);
|
|
58
|
+
_functions = new core_1.KoolbaseFunctions(config, () => _auth?.validAccessToken() ?? Promise.resolve(null), async () => { await _auth?.clearStoredSession(); });
|
|
59
|
+
// One anonymous device id for the whole SDK — bucketing (flags), targeting
|
|
60
|
+
// (code push), and registration keying (messaging) must all agree on it.
|
|
61
|
+
const deviceId = await (0, core_1.getOrCreateDeviceId)();
|
|
62
|
+
_flags = new core_1.KoolbaseFlags(config, deviceId);
|
|
63
|
+
// Initialize analytics
|
|
64
|
+
if (config.analyticsEnabled !== false) {
|
|
65
|
+
_analytics = new core_1.KoolbaseAnalytics(config);
|
|
66
|
+
await _analytics.init(config.appVersion);
|
|
67
|
+
}
|
|
68
|
+
// Initialize messaging
|
|
69
|
+
if (config.messagingEnabled !== false) {
|
|
70
|
+
_messaging = new core_1.KoolbaseMessaging(config);
|
|
71
|
+
_messaging.setDeviceId(deviceId);
|
|
72
|
+
}
|
|
73
|
+
_initialized = true;
|
|
74
|
+
},
|
|
75
|
+
get auth() {
|
|
76
|
+
ensureInitialized();
|
|
77
|
+
return _auth;
|
|
78
|
+
},
|
|
79
|
+
get db() {
|
|
80
|
+
ensureInitialized();
|
|
81
|
+
return _db;
|
|
82
|
+
},
|
|
83
|
+
get storage() {
|
|
84
|
+
ensureInitialized();
|
|
85
|
+
return _storage;
|
|
86
|
+
},
|
|
87
|
+
get realtime() {
|
|
88
|
+
ensureInitialized();
|
|
89
|
+
return _realtime;
|
|
90
|
+
},
|
|
91
|
+
get functions() {
|
|
92
|
+
ensureInitialized();
|
|
93
|
+
return _functions;
|
|
94
|
+
},
|
|
95
|
+
isEnabled(key) {
|
|
96
|
+
ensureInitialized();
|
|
97
|
+
return _flags.isEnabled(key);
|
|
98
|
+
},
|
|
99
|
+
configString(key, fallback = '') {
|
|
100
|
+
ensureInitialized();
|
|
101
|
+
return _flags.getString(key, fallback);
|
|
102
|
+
},
|
|
103
|
+
configNumber(key, fallback = 0) {
|
|
104
|
+
ensureInitialized();
|
|
105
|
+
return _flags.getNumber(key, fallback);
|
|
106
|
+
},
|
|
107
|
+
configBool(key, fallback = false) {
|
|
108
|
+
ensureInitialized();
|
|
109
|
+
return _flags.getBool(key, fallback);
|
|
110
|
+
},
|
|
111
|
+
get analytics() {
|
|
112
|
+
ensureInitialized();
|
|
113
|
+
return _analytics;
|
|
114
|
+
},
|
|
115
|
+
get messaging() {
|
|
116
|
+
ensureInitialized();
|
|
117
|
+
return _messaging;
|
|
118
|
+
},
|
|
119
|
+
checkVersion(currentVersion) {
|
|
120
|
+
ensureInitialized();
|
|
121
|
+
return _flags.checkVersion(currentVersion);
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
var auth_storage_js_1 = require("./auth-storage.js");
|
|
125
|
+
Object.defineProperty(exports, "SecureAuthStorage", { enumerable: true, get: function () { return auth_storage_js_1.SecureAuthStorage; } });
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.reactNativePlatform = reactNativePlatform;
|
|
7
|
+
const async_storage_1 = __importDefault(require("@react-native-async-storage/async-storage"));
|
|
8
|
+
const netinfo_1 = __importDefault(require("@react-native-community/netinfo"));
|
|
9
|
+
const react_native_1 = require("react-native");
|
|
10
|
+
const auth_storage_js_1 = require("./auth-storage.js");
|
|
11
|
+
// The React Native host, expressed through the platform seam. This is the
|
|
12
|
+
// only file in the package that imports a native module; everything the SDK
|
|
13
|
+
// does with storage, connectivity, lifecycle or platform identity goes
|
|
14
|
+
// through the adapter it returns.
|
|
15
|
+
function reactNativePlatform() {
|
|
16
|
+
return {
|
|
17
|
+
storage: {
|
|
18
|
+
getItem: (k) => async_storage_1.default.getItem(k),
|
|
19
|
+
setItem: (k, v) => async_storage_1.default.setItem(k, v),
|
|
20
|
+
removeItem: (k) => async_storage_1.default.removeItem(k),
|
|
21
|
+
getAllKeys: async () => Array.from(await async_storage_1.default.getAllKeys()),
|
|
22
|
+
},
|
|
23
|
+
network: {
|
|
24
|
+
onChange: (cb) => netinfo_1.default.addEventListener(state => {
|
|
25
|
+
cb(Boolean(state.isConnected) && state.isInternetReachable !== false);
|
|
26
|
+
}),
|
|
27
|
+
},
|
|
28
|
+
lifecycle: {
|
|
29
|
+
onBackground: (cb) => {
|
|
30
|
+
const sub = react_native_1.AppState.addEventListener('change', (state) => {
|
|
31
|
+
if (state === 'background' || state === 'inactive')
|
|
32
|
+
cb();
|
|
33
|
+
});
|
|
34
|
+
return () => sub.remove();
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
info: {
|
|
38
|
+
os: String(react_native_1.Platform.OS),
|
|
39
|
+
version: String(react_native_1.Platform.Version),
|
|
40
|
+
},
|
|
41
|
+
authStorage: () => ((0, auth_storage_js_1.isKeychainAvailable)() ? new auth_storage_js_1.SecureAuthStorage() : null),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { KoolbaseAuthStorage, KoolbaseSession } from '@koolbase/core';
|
|
2
|
+
/**
|
|
3
|
+
* Probe whether react-native-keychain is installed without throwing.
|
|
4
|
+
* Used by KoolbaseAuth to decide whether to instantiate a default
|
|
5
|
+
* SecureAuthStorage or proceed without persistence.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isKeychainAvailable(): boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Default secure storage implementation backed by `react-native-keychain`.
|
|
10
|
+
*
|
|
11
|
+
* - iOS: Keychain (encrypted, never synced via iCloud by default)
|
|
12
|
+
* - Android: Android Keystore-backed encryption
|
|
13
|
+
*
|
|
14
|
+
* Requires `react-native-keychain` as a peer dependency. Apps that prefer a
|
|
15
|
+
* different secure backend (e.g. `expo-secure-store`,
|
|
16
|
+
* `react-native-encrypted-storage`, an in-memory mock for testing, or a
|
|
17
|
+
* compliance-grade encryption layer) should implement the
|
|
18
|
+
* {@link KoolbaseAuthStorage} interface and pass it via
|
|
19
|
+
* `KoolbaseConfig.authStorage`.
|
|
20
|
+
*/
|
|
21
|
+
export declare class SecureAuthStorage implements KoolbaseAuthStorage {
|
|
22
|
+
private static readonly SERVICE;
|
|
23
|
+
saveSession(session: KoolbaseSession): Promise<void>;
|
|
24
|
+
readSession(): Promise<KoolbaseSession | null>;
|
|
25
|
+
clear(): Promise<void>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Lazy-load react-native-keychain so apps without it installed (e.g. Expo Go,
|
|
2
|
+
// or those providing a custom adapter) can still import this module without
|
|
3
|
+
// crashing. The default SecureAuthStorage will throw a clear error on first
|
|
4
|
+
// use if the peer dependency is missing.
|
|
5
|
+
let _keychain = null;
|
|
6
|
+
let _keychainAttempted = false;
|
|
7
|
+
function loadKeychain() {
|
|
8
|
+
if (!_keychainAttempted) {
|
|
9
|
+
_keychainAttempted = true;
|
|
10
|
+
try {
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
12
|
+
_keychain = require('react-native-keychain');
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
_keychain = null;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
if (!_keychain) {
|
|
19
|
+
throw new Error('[Koolbase] SecureAuthStorage requires react-native-keychain. ' +
|
|
20
|
+
'Install it with:\n npm install react-native-keychain\n' +
|
|
21
|
+
'Or provide your own storage adapter via ' +
|
|
22
|
+
'KoolbaseConfig.authStorage. For Expo Go (where ' +
|
|
23
|
+
'react-native-keychain is unavailable), implement KoolbaseAuthStorage ' +
|
|
24
|
+
'with expo-secure-store and pass it via authStorage.');
|
|
25
|
+
}
|
|
26
|
+
return _keychain;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Probe whether react-native-keychain is installed without throwing.
|
|
30
|
+
* Used by KoolbaseAuth to decide whether to instantiate a default
|
|
31
|
+
* SecureAuthStorage or proceed without persistence.
|
|
32
|
+
*/
|
|
33
|
+
export function isKeychainAvailable() {
|
|
34
|
+
if (!_keychainAttempted) {
|
|
35
|
+
_keychainAttempted = true;
|
|
36
|
+
try {
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
38
|
+
_keychain = require('react-native-keychain');
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
_keychain = null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return _keychain !== null;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Default secure storage implementation backed by `react-native-keychain`.
|
|
48
|
+
*
|
|
49
|
+
* - iOS: Keychain (encrypted, never synced via iCloud by default)
|
|
50
|
+
* - Android: Android Keystore-backed encryption
|
|
51
|
+
*
|
|
52
|
+
* Requires `react-native-keychain` as a peer dependency. Apps that prefer a
|
|
53
|
+
* different secure backend (e.g. `expo-secure-store`,
|
|
54
|
+
* `react-native-encrypted-storage`, an in-memory mock for testing, or a
|
|
55
|
+
* compliance-grade encryption layer) should implement the
|
|
56
|
+
* {@link KoolbaseAuthStorage} interface and pass it via
|
|
57
|
+
* `KoolbaseConfig.authStorage`.
|
|
58
|
+
*/
|
|
59
|
+
export class SecureAuthStorage {
|
|
60
|
+
async saveSession(session) {
|
|
61
|
+
const Keychain = loadKeychain();
|
|
62
|
+
await Keychain.setGenericPassword('session', JSON.stringify(session), { service: SecureAuthStorage.SERVICE });
|
|
63
|
+
}
|
|
64
|
+
async readSession() {
|
|
65
|
+
let Keychain;
|
|
66
|
+
try {
|
|
67
|
+
Keychain = loadKeychain();
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// Peer dep missing — caller will fall back to no persistence.
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
const credentials = await Keychain.getGenericPassword({
|
|
75
|
+
service: SecureAuthStorage.SERVICE,
|
|
76
|
+
});
|
|
77
|
+
if (!credentials || !credentials.password)
|
|
78
|
+
return null;
|
|
79
|
+
return JSON.parse(credentials.password);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// Corrupt data, schema mismatch, or platform-level keychain error.
|
|
83
|
+
// Treat as no session — caller will trigger fresh login.
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async clear() {
|
|
88
|
+
let Keychain;
|
|
89
|
+
try {
|
|
90
|
+
Keychain = loadKeychain();
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return; // No-op if peer dep missing.
|
|
94
|
+
}
|
|
95
|
+
await Keychain.resetGenericPassword({
|
|
96
|
+
service: SecureAuthStorage.SERVICE,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
SecureAuthStorage.SERVICE = 'koolbase_session_v1';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export * from '@koolbase/core';
|
|
2
|
+
export { reactNativePlatform } from './platform.js';
|
|
3
|
+
import { KoolbaseAuth, KoolbaseDatabase, KoolbaseStorage, KoolbaseRealtime, KoolbaseFunctions, KoolbaseAnalytics, KoolbaseMessaging, type KoolbaseConfig, type VersionCheckResult } from '@koolbase/core';
|
|
4
|
+
export declare const Koolbase: {
|
|
5
|
+
initialize(config: KoolbaseConfig): Promise<void>;
|
|
6
|
+
readonly auth: KoolbaseAuth;
|
|
7
|
+
readonly db: KoolbaseDatabase;
|
|
8
|
+
readonly storage: KoolbaseStorage;
|
|
9
|
+
readonly realtime: KoolbaseRealtime;
|
|
10
|
+
readonly functions: KoolbaseFunctions;
|
|
11
|
+
isEnabled(key: string): boolean;
|
|
12
|
+
configString(key: string, fallback?: string): string;
|
|
13
|
+
configNumber(key: string, fallback?: number): number;
|
|
14
|
+
configBool(key: string, fallback?: boolean): boolean;
|
|
15
|
+
readonly analytics: KoolbaseAnalytics;
|
|
16
|
+
readonly messaging: KoolbaseMessaging;
|
|
17
|
+
checkVersion(currentVersion: string): VersionCheckResult;
|
|
18
|
+
};
|
|
19
|
+
export { SecureAuthStorage } from './auth-storage.js';
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// @koolbase/react-native — composes @koolbase/core for a React Native host.
|
|
2
|
+
//
|
|
3
|
+
// Everything the core exports is re-exported here unchanged, so an app that
|
|
4
|
+
// installed this package before the split sees the same surface. What this
|
|
5
|
+
// file adds is the composition: one Koolbase singleton, initialized with the
|
|
6
|
+
// React Native platform adapter and keychain-backed session storage.
|
|
7
|
+
export * from '@koolbase/core';
|
|
8
|
+
export { reactNativePlatform } from './platform.js';
|
|
9
|
+
import { KoolbaseAuth, KoolbaseDatabase, KoolbaseStorage, KoolbaseRealtime, KoolbaseFunctions, KoolbaseFlags, KoolbaseAnalytics, KoolbaseMessaging, getOrCreateDeviceId, setPlatform, } from '@koolbase/core';
|
|
10
|
+
import { reactNativePlatform } from './platform.js';
|
|
11
|
+
let _auth = null;
|
|
12
|
+
let _db = null;
|
|
13
|
+
let _storage = null;
|
|
14
|
+
let _realtime = null;
|
|
15
|
+
let _functions = null;
|
|
16
|
+
let _flags = null;
|
|
17
|
+
let _analytics = null;
|
|
18
|
+
let _messaging = null;
|
|
19
|
+
let _initialized = false;
|
|
20
|
+
function ensureInitialized() {
|
|
21
|
+
if (!_initialized) {
|
|
22
|
+
throw new Error('Koolbase not initialized. Call Koolbase.initialize() first.');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export const Koolbase = {
|
|
26
|
+
async initialize(config) {
|
|
27
|
+
if (_initialized)
|
|
28
|
+
return;
|
|
29
|
+
// The host platform, installed before any subsystem touches storage or
|
|
30
|
+
// the network. Tests leave this unset and run on the in-memory default.
|
|
31
|
+
setPlatform(config.platform ?? reactNativePlatform());
|
|
32
|
+
_auth = new KoolbaseAuth(config);
|
|
33
|
+
_db = new KoolbaseDatabase(config, () => _auth?.currentUser?.id ?? null, () => _auth?.validAccessToken() ?? Promise.resolve(null),
|
|
34
|
+
// A session the server refuses is not a session. Clearing it here means an
|
|
35
|
+
// app catching KoolbaseUnauthenticatedError is already signed out and can
|
|
36
|
+
// route to login, rather than looping on a dead token.
|
|
37
|
+
async () => { await _auth?.clearStoredSession(); });
|
|
38
|
+
_storage = new KoolbaseStorage(config, () => _auth?.validAccessToken() ?? Promise.resolve(null), async () => { await _auth?.clearStoredSession(); });
|
|
39
|
+
_realtime = new KoolbaseRealtime(config, () => _auth?.validAccessToken() ?? Promise.resolve(null), () => _auth?.currentUser?.id ?? null);
|
|
40
|
+
_functions = new KoolbaseFunctions(config, () => _auth?.validAccessToken() ?? Promise.resolve(null), async () => { await _auth?.clearStoredSession(); });
|
|
41
|
+
// One anonymous device id for the whole SDK — bucketing (flags), targeting
|
|
42
|
+
// (code push), and registration keying (messaging) must all agree on it.
|
|
43
|
+
const deviceId = await getOrCreateDeviceId();
|
|
44
|
+
_flags = new KoolbaseFlags(config, deviceId);
|
|
45
|
+
// Initialize analytics
|
|
46
|
+
if (config.analyticsEnabled !== false) {
|
|
47
|
+
_analytics = new KoolbaseAnalytics(config);
|
|
48
|
+
await _analytics.init(config.appVersion);
|
|
49
|
+
}
|
|
50
|
+
// Initialize messaging
|
|
51
|
+
if (config.messagingEnabled !== false) {
|
|
52
|
+
_messaging = new KoolbaseMessaging(config);
|
|
53
|
+
_messaging.setDeviceId(deviceId);
|
|
54
|
+
}
|
|
55
|
+
_initialized = true;
|
|
56
|
+
},
|
|
57
|
+
get auth() {
|
|
58
|
+
ensureInitialized();
|
|
59
|
+
return _auth;
|
|
60
|
+
},
|
|
61
|
+
get db() {
|
|
62
|
+
ensureInitialized();
|
|
63
|
+
return _db;
|
|
64
|
+
},
|
|
65
|
+
get storage() {
|
|
66
|
+
ensureInitialized();
|
|
67
|
+
return _storage;
|
|
68
|
+
},
|
|
69
|
+
get realtime() {
|
|
70
|
+
ensureInitialized();
|
|
71
|
+
return _realtime;
|
|
72
|
+
},
|
|
73
|
+
get functions() {
|
|
74
|
+
ensureInitialized();
|
|
75
|
+
return _functions;
|
|
76
|
+
},
|
|
77
|
+
isEnabled(key) {
|
|
78
|
+
ensureInitialized();
|
|
79
|
+
return _flags.isEnabled(key);
|
|
80
|
+
},
|
|
81
|
+
configString(key, fallback = '') {
|
|
82
|
+
ensureInitialized();
|
|
83
|
+
return _flags.getString(key, fallback);
|
|
84
|
+
},
|
|
85
|
+
configNumber(key, fallback = 0) {
|
|
86
|
+
ensureInitialized();
|
|
87
|
+
return _flags.getNumber(key, fallback);
|
|
88
|
+
},
|
|
89
|
+
configBool(key, fallback = false) {
|
|
90
|
+
ensureInitialized();
|
|
91
|
+
return _flags.getBool(key, fallback);
|
|
92
|
+
},
|
|
93
|
+
get analytics() {
|
|
94
|
+
ensureInitialized();
|
|
95
|
+
return _analytics;
|
|
96
|
+
},
|
|
97
|
+
get messaging() {
|
|
98
|
+
ensureInitialized();
|
|
99
|
+
return _messaging;
|
|
100
|
+
},
|
|
101
|
+
checkVersion(currentVersion) {
|
|
102
|
+
ensureInitialized();
|
|
103
|
+
return _flags.checkVersion(currentVersion);
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
export { SecureAuthStorage } from './auth-storage.js';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
2
|
+
import NetInfo from '@react-native-community/netinfo';
|
|
3
|
+
import { AppState, Platform } from 'react-native';
|
|
4
|
+
import { SecureAuthStorage, isKeychainAvailable } from './auth-storage.js';
|
|
5
|
+
// The React Native host, expressed through the platform seam. This is the
|
|
6
|
+
// only file in the package that imports a native module; everything the SDK
|
|
7
|
+
// does with storage, connectivity, lifecycle or platform identity goes
|
|
8
|
+
// through the adapter it returns.
|
|
9
|
+
export function reactNativePlatform() {
|
|
10
|
+
return {
|
|
11
|
+
storage: {
|
|
12
|
+
getItem: (k) => AsyncStorage.getItem(k),
|
|
13
|
+
setItem: (k, v) => AsyncStorage.setItem(k, v),
|
|
14
|
+
removeItem: (k) => AsyncStorage.removeItem(k),
|
|
15
|
+
getAllKeys: async () => Array.from(await AsyncStorage.getAllKeys()),
|
|
16
|
+
},
|
|
17
|
+
network: {
|
|
18
|
+
onChange: (cb) => NetInfo.addEventListener(state => {
|
|
19
|
+
cb(Boolean(state.isConnected) && state.isInternetReachable !== false);
|
|
20
|
+
}),
|
|
21
|
+
},
|
|
22
|
+
lifecycle: {
|
|
23
|
+
onBackground: (cb) => {
|
|
24
|
+
const sub = AppState.addEventListener('change', (state) => {
|
|
25
|
+
if (state === 'background' || state === 'inactive')
|
|
26
|
+
cb();
|
|
27
|
+
});
|
|
28
|
+
return () => sub.remove();
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
info: {
|
|
32
|
+
os: String(Platform.OS),
|
|
33
|
+
version: String(Platform.Version),
|
|
34
|
+
},
|
|
35
|
+
authStorage: () => (isKeychainAvailable() ? new SecureAuthStorage() : null),
|
|
36
|
+
};
|
|
37
|
+
}
|
package/package.json
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@koolbase/react-native",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.0.1",
|
|
4
4
|
"description": "React Native SDK for Koolbase \u2014 auth, database, storage, realtime, feature flags, and functions in one package.",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
5
|
+
"main": "./dist/cjs/index.js",
|
|
6
|
+
"types": "./dist/esm/index.d.ts",
|
|
7
7
|
"files": [
|
|
8
|
-
"dist"
|
|
8
|
+
"dist",
|
|
9
|
+
"CHANGELOG.md"
|
|
9
10
|
],
|
|
10
11
|
"scripts": {
|
|
11
|
-
"build": "
|
|
12
|
-
"prepare": "npm run build",
|
|
13
|
-
"test": "jest"
|
|
12
|
+
"build": "node ../../scripts/build-package.js react-native"
|
|
14
13
|
},
|
|
15
14
|
"keywords": [
|
|
16
15
|
"koolbase",
|
|
@@ -19,40 +18,41 @@
|
|
|
19
18
|
"firebase-alternative",
|
|
20
19
|
"flutter"
|
|
21
20
|
],
|
|
22
|
-
"author": "Kennedy Owusu",
|
|
23
21
|
"license": "MIT",
|
|
24
|
-
"homepage": "https://koolbase.com",
|
|
25
22
|
"repository": {
|
|
26
23
|
"type": "git",
|
|
27
24
|
"url": "https://github.com/koolbase/koolbase-react-native"
|
|
28
25
|
},
|
|
29
|
-
"
|
|
30
|
-
"@
|
|
31
|
-
"@types/jszip": "^3.4.0",
|
|
32
|
-
"@types/node": "^25.9.1",
|
|
33
|
-
"jest": "^30.4.2",
|
|
34
|
-
"react-native": "^0.85.3",
|
|
35
|
-
"react-native-keychain": "^10.0.0",
|
|
36
|
-
"ts-jest": "^29.4.12",
|
|
37
|
-
"typescript": "^5.0.0",
|
|
38
|
-
"@react-native-async-storage/async-storage": "^3.0.2",
|
|
39
|
-
"@react-native-community/netinfo": "^12.0.1"
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@koolbase/core": "10.0.1"
|
|
40
28
|
},
|
|
41
29
|
"peerDependencies": {
|
|
42
|
-
"react-native": ">=0.70.0",
|
|
43
|
-
"react-native-keychain": ">=8.0.0",
|
|
44
30
|
"@react-native-async-storage/async-storage": "^3.0.2",
|
|
45
|
-
"@react-native-community/netinfo": "^12.0.1"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
"jszip": "^3.10.1"
|
|
49
|
-
},
|
|
50
|
-
"publishConfig": {
|
|
51
|
-
"access": "public"
|
|
31
|
+
"@react-native-community/netinfo": "^12.0.1",
|
|
32
|
+
"react-native": ">=0.70.0",
|
|
33
|
+
"react-native-keychain": ">=8.0.0"
|
|
52
34
|
},
|
|
53
35
|
"peerDependenciesMeta": {
|
|
54
36
|
"react-native-keychain": {
|
|
55
37
|
"optional": true
|
|
56
38
|
}
|
|
57
|
-
}
|
|
39
|
+
},
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"access": "public"
|
|
42
|
+
},
|
|
43
|
+
"module": "./dist/esm/index.js",
|
|
44
|
+
"exports": {
|
|
45
|
+
".": {
|
|
46
|
+
"import": {
|
|
47
|
+
"types": "./dist/esm/index.d.ts",
|
|
48
|
+
"default": "./dist/esm/index.js"
|
|
49
|
+
},
|
|
50
|
+
"require": {
|
|
51
|
+
"types": "./dist/cjs/index.d.ts",
|
|
52
|
+
"default": "./dist/cjs/index.js"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"./package.json": "./package.json"
|
|
56
|
+
},
|
|
57
|
+
"sideEffects": false
|
|
58
58
|
}
|
package/dist/analytics.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { KoolbaseConfig } from './types';
|
|
2
|
-
export declare class KoolbaseAnalytics {
|
|
3
|
-
private config;
|
|
4
|
-
private queue;
|
|
5
|
-
private deviceId;
|
|
6
|
-
private userId?;
|
|
7
|
-
private environmentId?;
|
|
8
|
-
private userProperties;
|
|
9
|
-
private sessionId;
|
|
10
|
-
private appVersion;
|
|
11
|
-
private flushTimer?;
|
|
12
|
-
private initialized;
|
|
13
|
-
constructor(config: KoolbaseConfig);
|
|
14
|
-
init(appVersion?: string): Promise<void>;
|
|
15
|
-
track(eventName: string, properties?: Record<string, unknown>): void;
|
|
16
|
-
screenView(screenName: string, properties?: Record<string, unknown>): void;
|
|
17
|
-
identify(userId: string): void;
|
|
18
|
-
setUserProperty(key: string, value: unknown): void;
|
|
19
|
-
setUserProperties(properties: Record<string, unknown>): void;
|
|
20
|
-
setEnvironment(environmentId: string): void;
|
|
21
|
-
reset(): void;
|
|
22
|
-
flush(): Promise<void>;
|
|
23
|
-
dispose(): Promise<void>;
|
|
24
|
-
}
|