@delali/narsil-react-native 0.0.0-stage → 0.3.1-next.146
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 +201 -0
- package/NarsilReactNative.podspec +57 -0
- package/README.md +46 -2
- package/android/CMakeLists.txt +48 -0
- package/android/build.gradle +151 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/cpp/AndroidEnvironment.cpp +44 -0
- package/android/src/main/cpp/AndroidEnvironment.hpp +11 -0
- package/android/src/main/cpp/cpp-adapter.cpp +11 -0
- package/android/src/main/java/com/margelo/nitro/narsil/NarsilAndroidEnvironment.kt +29 -0
- package/android/src/main/java/com/margelo/nitro/narsil/NarsilReactNativePackage.kt +22 -0
- package/app.plugin.js +25 -0
- package/cpp/AttachedField.cpp +234 -0
- package/cpp/AttachedField.hpp +61 -0
- package/cpp/Compression.cpp +113 -0
- package/cpp/Compression.hpp +16 -0
- package/cpp/GraphHeldAlone.cpp +29 -0
- package/cpp/GraphHeldAlone.hpp +25 -0
- package/cpp/HostMemory.cpp +123 -0
- package/cpp/HostMemory.hpp +53 -0
- package/cpp/HybridNarsilCoreImpl.cpp +390 -0
- package/cpp/HybridNarsilCoreImpl.hpp +68 -0
- package/cpp/HybridNarsilFilesImpl.cpp +245 -0
- package/cpp/HybridNarsilFilesImpl.hpp +34 -0
- package/cpp/HybridNarsilHostImpl.cpp +126 -0
- package/cpp/HybridNarsilHostImpl.hpp +42 -0
- package/cpp/NativeAtomics.cpp +110 -0
- package/cpp/NativeAtomics.hpp +11 -0
- package/cpp/ProcessInfo.cpp +83 -0
- package/cpp/ProcessInfo.hpp +11 -0
- package/cpp/ThreadPriority.cpp +77 -0
- package/cpp/ThreadPriority.hpp +8 -0
- package/cpp/WorkletRuntimeDispatcher.cpp +61 -0
- package/cpp/WorkletRuntimeDispatcher.hpp +9 -0
- package/cpp/core/include/narsil_core.h +208 -0
- package/cpp/core/src/connect.c +213 -0
- package/cpp/core/src/distance.c +103 -0
- package/cpp/core/src/files.c +99 -0
- package/cpp/core/src/heap.c +84 -0
- package/cpp/core/src/internal.h +284 -0
- package/cpp/core/src/kernels_code.c +209 -0
- package/cpp/core/src/kernels_float.c +197 -0
- package/cpp/core/src/kernels_pair.c +133 -0
- package/cpp/core/src/last_links.c +145 -0
- package/cpp/core/src/links.c +195 -0
- package/cpp/core/src/locks.c +168 -0
- package/cpp/core/src/nearest_links.c +147 -0
- package/cpp/core/src/place.c +215 -0
- package/cpp/core/src/quantize.c +226 -0
- package/cpp/core/src/records.c +97 -0
- package/cpp/core/src/remove.c +205 -0
- package/cpp/core/src/vectors.c +139 -0
- package/cpp/core/src/walk.c +231 -0
- package/cpp/core/src/workspace.c +167 -0
- package/ios/PrivacyInfo.xcprivacy +23 -0
- package/lib/client.d.ts +19 -0
- package/lib/client.js +41 -0
- package/lib/constants.d.ts +9 -0
- package/lib/constants.js +9 -0
- package/lib/engine/byte-files.d.ts +5 -0
- package/lib/engine/byte-files.js +97 -0
- package/lib/engine/core.d.ts +3 -0
- package/lib/engine/core.js +113 -0
- package/lib/engine/files.d.ts +3 -0
- package/lib/engine/files.js +188 -0
- package/lib/engine/host.d.ts +13 -0
- package/lib/engine/host.js +102 -0
- package/lib/engine/install.d.ts +4 -0
- package/lib/engine/install.js +29 -0
- package/lib/engine/native-error.d.ts +1 -0
- package/lib/engine/native-error.js +12 -0
- package/lib/engine/stand-ins/atomics.d.ts +5 -0
- package/lib/engine/stand-ins/atomics.js +236 -0
- package/lib/engine/stand-ins/crypto.d.ts +2 -0
- package/lib/engine/stand-ins/crypto.js +65 -0
- package/lib/engine/stand-ins/process.d.ts +2 -0
- package/lib/engine/stand-ins/process.js +22 -0
- package/lib/engine/stand-ins/streams.d.ts +1 -0
- package/lib/engine/stand-ins/streams.js +31 -0
- package/lib/engine/stand-ins/structured-clone.d.ts +1 -0
- package/lib/engine/stand-ins/structured-clone.js +121 -0
- package/lib/engine/streamed.d.ts +6 -0
- package/lib/engine/streamed.js +29 -0
- package/lib/engine/transfer.d.ts +3 -0
- package/lib/engine/transfer.js +77 -0
- package/lib/errors.d.ts +25 -0
- package/lib/errors.js +59 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.js +2 -0
- package/lib/methods.d.ts +5 -0
- package/lib/methods.js +47 -0
- package/lib/native-objects.d.ts +2 -0
- package/lib/native-objects.js +24 -0
- package/lib/specs/core.nitro.d.ts +79 -0
- package/lib/specs/core.nitro.js +1 -0
- package/lib/specs/files.nitro.d.ts +36 -0
- package/lib/specs/files.nitro.js +1 -0
- package/lib/specs/host.nitro.d.ts +24 -0
- package/lib/specs/host.nitro.js +1 -0
- package/lib/transferred.d.ts +15 -0
- package/lib/transferred.js +6 -0
- package/lib/types.d.ts +136 -0
- package/lib/types.js +1 -0
- package/lib/worklets/app-turns.d.ts +1 -0
- package/lib/worklets/app-turns.js +44 -0
- package/lib/worklets/client.d.ts +30 -0
- package/lib/worklets/client.js +144 -0
- package/lib/worklets/index.d.ts +4 -0
- package/lib/worklets/index.js +2 -0
- package/lib/worklets/instances.d.ts +15 -0
- package/lib/worklets/instances.js +194 -0
- package/lib/worklets/json-part.d.ts +1 -0
- package/lib/worklets/json-part.js +42 -0
- package/lib/worklets/runtime.d.ts +25 -0
- package/lib/worklets/runtime.js +80 -0
- package/lib/worklets/transfer-queue.d.ts +7 -0
- package/lib/worklets/transfer-queue.js +79 -0
- package/lib/worklets/types.d.ts +26 -0
- package/lib/worklets/types.js +1 -0
- package/nitro.json +32 -0
- package/nitrogen/generated/.gitattributes +1 -0
- package/nitrogen/generated/android/NarsilReactNative+autolinking.cmake +85 -0
- package/nitrogen/generated/android/NarsilReactNative+autolinking.gradle +27 -0
- package/nitrogen/generated/android/NarsilReactNativeOnLoad.cpp +69 -0
- package/nitrogen/generated/android/NarsilReactNativeOnLoad.hpp +34 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/narsil/NarsilReactNativeOnLoad.kt +35 -0
- package/nitrogen/generated/ios/NarsilReactNative+autolinking.rb +62 -0
- package/nitrogen/generated/ios/NarsilReactNative-Swift-Cxx-Bridge.cpp +17 -0
- package/nitrogen/generated/ios/NarsilReactNative-Swift-Cxx-Bridge.hpp +27 -0
- package/nitrogen/generated/ios/NarsilReactNative-Swift-Cxx-Umbrella.hpp +38 -0
- package/nitrogen/generated/ios/NarsilReactNativeAutolinking.mm +55 -0
- package/nitrogen/generated/ios/NarsilReactNativeAutolinking.swift +16 -0
- package/nitrogen/generated/shared/c++/DirectoryEntry.hpp +91 -0
- package/nitrogen/generated/shared/c++/FileStatus.hpp +103 -0
- package/nitrogen/generated/shared/c++/GraphMemory.hpp +120 -0
- package/nitrogen/generated/shared/c++/HybridNarsilAttachedGraphSpec.cpp +21 -0
- package/nitrogen/generated/shared/c++/HybridNarsilAttachedGraphSpec.hpp +62 -0
- package/nitrogen/generated/shared/c++/HybridNarsilAttachedStoreSpec.cpp +21 -0
- package/nitrogen/generated/shared/c++/HybridNarsilAttachedStoreSpec.hpp +62 -0
- package/nitrogen/generated/shared/c++/HybridNarsilCoreSpec.cpp +35 -0
- package/nitrogen/generated/shared/c++/HybridNarsilCoreSpec.hpp +100 -0
- package/nitrogen/generated/shared/c++/HybridNarsilFilesSpec.cpp +37 -0
- package/nitrogen/generated/shared/c++/HybridNarsilFilesSpec.hpp +86 -0
- package/nitrogen/generated/shared/c++/HybridNarsilHostSpec.cpp +34 -0
- package/nitrogen/generated/shared/c++/HybridNarsilHostSpec.hpp +78 -0
- package/nitrogen/generated/shared/c++/MemoryView.hpp +91 -0
- package/nitrogen/generated/shared/c++/NativeConnectOutcome.hpp +87 -0
- package/nitrogen/generated/shared/c++/NativeScores.hpp +87 -0
- package/nitrogen/generated/shared/c++/NativeSearchHits.hpp +91 -0
- package/nitrogen/generated/shared/c++/ProcessMemory.hpp +87 -0
- package/nitrogen/generated/shared/c++/StoreMemory.hpp +142 -0
- package/package.json +87 -3
- package/react-native.config.js +8 -0
- package/src/client.ts +44 -0
- package/src/constants.ts +9 -0
- package/src/engine/byte-files.ts +99 -0
- package/src/engine/core.ts +162 -0
- package/src/engine/files.ts +186 -0
- package/src/engine/host.ts +111 -0
- package/src/engine/install.ts +31 -0
- package/src/engine/native-error.ts +10 -0
- package/src/engine/stand-ins/atomics.ts +288 -0
- package/src/engine/stand-ins/crypto.ts +81 -0
- package/src/engine/stand-ins/process.ts +30 -0
- package/src/engine/stand-ins/streams.ts +45 -0
- package/src/engine/stand-ins/structured-clone.ts +118 -0
- package/src/engine/streamed.ts +40 -0
- package/src/engine/transfer.ts +72 -0
- package/src/errors.ts +73 -0
- package/src/index.ts +3 -0
- package/src/methods.ts +52 -0
- package/src/native-objects.ts +30 -0
- package/src/specs/core.nitro.ts +140 -0
- package/src/specs/files.nitro.ts +42 -0
- package/src/specs/host.nitro.ts +30 -0
- package/src/transferred.ts +18 -0
- package/src/types.ts +164 -0
- package/src/worklets/app-turns.ts +48 -0
- package/src/worklets/client.ts +165 -0
- package/src/worklets/index.ts +4 -0
- package/src/worklets/instances.ts +231 -0
- package/src/worklets/json-part.ts +38 -0
- package/src/worklets/runtime.ts +190 -0
- package/src/worklets/transfer-queue.ts +98 -0
- package/src/worklets/types.ts +37 -0
package/lib/errors.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { isTransferredError } from './transferred';
|
|
2
|
+
const NARSIL_ERROR_MARKER = Symbol.for('@delali/narsil.NarsilError');
|
|
3
|
+
const NARSIL_ERROR_NAME = 'NarsilError';
|
|
4
|
+
const NATIVE_DEPENDENCY_MISSING = 'NATIVE_DEPENDENCY_MISSING';
|
|
5
|
+
const NATIVE_DEPENDENCY_MISSING_MESSAGE = 'This app build does not include the Narsil native module, as happens in Expo Go and on 32-bit Android. Install `@delali/narsil-react-native` and `react-native-nitro-modules`, then make a development build with `npx expo run:ios` or `npx expo run:android`, or, in an app without Expo, run `pod install` in the `ios` folder and rebuild the app for each platform.';
|
|
6
|
+
/**
|
|
7
|
+
* Reports whether a value is an error that the Narsil engine raised, whether
|
|
8
|
+
* it reached the app from the engine's runtime or from this package.
|
|
9
|
+
*
|
|
10
|
+
* @param value - Anything that a rejected promise or a `catch` block holds.
|
|
11
|
+
* @returns True when the value carries a Narsil error code.
|
|
12
|
+
*
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
15
|
+
export function isNarsilError(value) {
|
|
16
|
+
return typeof value === 'object' && value !== null && NARSIL_ERROR_MARKER in value;
|
|
17
|
+
}
|
|
18
|
+
function narsilError(message, code, details) {
|
|
19
|
+
const error = new Error(message);
|
|
20
|
+
error.name = NARSIL_ERROR_NAME;
|
|
21
|
+
Object.defineProperty(error, 'code', { value: code, enumerable: true });
|
|
22
|
+
Object.defineProperty(error, 'details', { value: details, enumerable: true });
|
|
23
|
+
Object.defineProperty(error, NARSIL_ERROR_MARKER, { value: true });
|
|
24
|
+
return error;
|
|
25
|
+
}
|
|
26
|
+
export function nativeDependencyMissing(cause) {
|
|
27
|
+
return narsilError(NATIVE_DEPENDENCY_MISSING_MESSAGE, NATIVE_DEPENDENCY_MISSING, {
|
|
28
|
+
cause: cause instanceof Error ? cause.message : String(cause),
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
export function rebuiltError(transferred) {
|
|
32
|
+
const details = rebuiltValue(transferred.details);
|
|
33
|
+
if (transferred.name === NARSIL_ERROR_NAME && transferred.code !== undefined) {
|
|
34
|
+
const record = typeof details === 'object' && details !== null ? details : {};
|
|
35
|
+
return narsilError(transferred.message, transferred.code, record);
|
|
36
|
+
}
|
|
37
|
+
const error = new Error(transferred.message);
|
|
38
|
+
error.name = transferred.name;
|
|
39
|
+
if (transferred.code !== undefined)
|
|
40
|
+
Object.defineProperty(error, 'code', { value: transferred.code, enumerable: true });
|
|
41
|
+
if (details !== undefined)
|
|
42
|
+
Object.defineProperty(error, 'details', { value: details, enumerable: true });
|
|
43
|
+
return error;
|
|
44
|
+
}
|
|
45
|
+
export function rebuiltValue(value) {
|
|
46
|
+
if (value === null || typeof value !== 'object')
|
|
47
|
+
return value;
|
|
48
|
+
if (isTransferredError(value))
|
|
49
|
+
return rebuiltError(value);
|
|
50
|
+
const prototype = Object.getPrototypeOf(value);
|
|
51
|
+
if (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null)
|
|
52
|
+
return value;
|
|
53
|
+
if (Array.isArray(value))
|
|
54
|
+
return value.map(rebuiltValue);
|
|
55
|
+
const record = {};
|
|
56
|
+
for (const key of Object.keys(value))
|
|
57
|
+
record[key] = rebuiltValue(value[key]);
|
|
58
|
+
return record;
|
|
59
|
+
}
|
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
package/lib/methods.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const FORWARDED_METHODS: readonly ["createIndex", "dropIndex", "listIndexes", "getStats", "getPartitionStats", "get", "getMultiple", "has", "countDocuments", "listDocuments", "query", "preflight", "suggest", "rebuildAnalysis", "restore", "importDocumentExport", "checkpoint", "clear", "rebalance", "updatePartitionConfig", "getMemoryStats", "compactVectors", "optimizeVectors", "vectorMaintenanceStatus", "open", "close", "insert", "insertBatch", "remove", "removeBatch", "update", "updateBatch", "waitForWrites", "updateSynonyms", "getSynonyms", "changeAnalysis", "updateBM25"];
|
|
2
|
+
export declare const STREAMED_METHODS: readonly ["snapshot", "exportDocuments", "snapshotToFile", "exportDocumentsToFile", "restoreFromFile", "importDocumentExportFromFile"];
|
|
3
|
+
export type ForwardedMethod = (typeof FORWARDED_METHODS)[number];
|
|
4
|
+
export type StreamedMethod = (typeof STREAMED_METHODS)[number];
|
|
5
|
+
export type EngineMethod = ForwardedMethod | StreamedMethod | 'shutdown';
|
package/lib/methods.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export const FORWARDED_METHODS = [
|
|
2
|
+
'createIndex',
|
|
3
|
+
'dropIndex',
|
|
4
|
+
'listIndexes',
|
|
5
|
+
'getStats',
|
|
6
|
+
'getPartitionStats',
|
|
7
|
+
'get',
|
|
8
|
+
'getMultiple',
|
|
9
|
+
'has',
|
|
10
|
+
'countDocuments',
|
|
11
|
+
'listDocuments',
|
|
12
|
+
'query',
|
|
13
|
+
'preflight',
|
|
14
|
+
'suggest',
|
|
15
|
+
'rebuildAnalysis',
|
|
16
|
+
'restore',
|
|
17
|
+
'importDocumentExport',
|
|
18
|
+
'checkpoint',
|
|
19
|
+
'clear',
|
|
20
|
+
'rebalance',
|
|
21
|
+
'updatePartitionConfig',
|
|
22
|
+
'getMemoryStats',
|
|
23
|
+
'compactVectors',
|
|
24
|
+
'optimizeVectors',
|
|
25
|
+
'vectorMaintenanceStatus',
|
|
26
|
+
'open',
|
|
27
|
+
'close',
|
|
28
|
+
'insert',
|
|
29
|
+
'insertBatch',
|
|
30
|
+
'remove',
|
|
31
|
+
'removeBatch',
|
|
32
|
+
'update',
|
|
33
|
+
'updateBatch',
|
|
34
|
+
'waitForWrites',
|
|
35
|
+
'updateSynonyms',
|
|
36
|
+
'getSynonyms',
|
|
37
|
+
'changeAnalysis',
|
|
38
|
+
'updateBM25',
|
|
39
|
+
];
|
|
40
|
+
export const STREAMED_METHODS = [
|
|
41
|
+
'snapshot',
|
|
42
|
+
'exportDocuments',
|
|
43
|
+
'snapshotToFile',
|
|
44
|
+
'exportDocumentsToFile',
|
|
45
|
+
'restoreFromFile',
|
|
46
|
+
'importDocumentExportFromFile',
|
|
47
|
+
];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { nativeDependencyMissing } from './errors';
|
|
2
|
+
let loading = null;
|
|
3
|
+
async function createNativeObjects() {
|
|
4
|
+
try {
|
|
5
|
+
const { NitroModules } = await import('react-native-nitro-modules');
|
|
6
|
+
return {
|
|
7
|
+
host: NitroModules.createHybridObject('NarsilHost'),
|
|
8
|
+
files: NitroModules.createHybridObject('NarsilFiles'),
|
|
9
|
+
core: NitroModules.createHybridObject('NarsilCore'),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
throw nativeDependencyMissing(error);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function loadNativeObjects() {
|
|
17
|
+
if (loading === null) {
|
|
18
|
+
loading = createNativeObjects();
|
|
19
|
+
loading.catch(() => {
|
|
20
|
+
loading = null;
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
return loading;
|
|
24
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { HybridObject } from 'react-native-nitro-modules';
|
|
2
|
+
export interface MemoryView {
|
|
3
|
+
buffer: ArrayBuffer;
|
|
4
|
+
byteOffset: number;
|
|
5
|
+
byteLength: number;
|
|
6
|
+
}
|
|
7
|
+
export interface GraphMemory {
|
|
8
|
+
graphHeader: MemoryView;
|
|
9
|
+
nodeLevels: MemoryView;
|
|
10
|
+
level0: MemoryView;
|
|
11
|
+
upperBase: MemoryView;
|
|
12
|
+
upper: MemoryView;
|
|
13
|
+
locks: MemoryView;
|
|
14
|
+
tombstones: MemoryView;
|
|
15
|
+
incoming: MemoryView;
|
|
16
|
+
nearestLinkDue: MemoryView;
|
|
17
|
+
heldLocks: MemoryView;
|
|
18
|
+
}
|
|
19
|
+
export interface StoreMemory {
|
|
20
|
+
storeHeader: MemoryView;
|
|
21
|
+
dimension: number;
|
|
22
|
+
bits: number;
|
|
23
|
+
recordsPerBlock: number;
|
|
24
|
+
vectorsPerBlock: number;
|
|
25
|
+
vectorStrideBytes: number;
|
|
26
|
+
codePresent: MemoryView;
|
|
27
|
+
centroid: MemoryView;
|
|
28
|
+
magnitudes: MemoryView;
|
|
29
|
+
present: MemoryView;
|
|
30
|
+
vectorFile: MemoryView;
|
|
31
|
+
vectorOffset: MemoryView;
|
|
32
|
+
vectorFiles: string[];
|
|
33
|
+
codeBlocks: MemoryView[];
|
|
34
|
+
vectorBlocks: MemoryView[];
|
|
35
|
+
}
|
|
36
|
+
export interface NativeSearchHits {
|
|
37
|
+
count: number;
|
|
38
|
+
ordinals: ArrayBuffer;
|
|
39
|
+
distances: ArrayBuffer;
|
|
40
|
+
}
|
|
41
|
+
export interface NativeScores {
|
|
42
|
+
status: number;
|
|
43
|
+
distances: ArrayBuffer;
|
|
44
|
+
}
|
|
45
|
+
export interface NativeConnectOutcome {
|
|
46
|
+
status: number;
|
|
47
|
+
wakes: ArrayBuffer;
|
|
48
|
+
}
|
|
49
|
+
export interface NarsilAttachedGraph extends HybridObject<{
|
|
50
|
+
ios: 'c++';
|
|
51
|
+
android: 'c++';
|
|
52
|
+
}> {
|
|
53
|
+
}
|
|
54
|
+
export interface NarsilAttachedStore extends HybridObject<{
|
|
55
|
+
ios: 'c++';
|
|
56
|
+
android: 'c++';
|
|
57
|
+
}> {
|
|
58
|
+
detach(): number;
|
|
59
|
+
}
|
|
60
|
+
export interface NarsilCore extends HybridObject<{
|
|
61
|
+
ios: 'c++';
|
|
62
|
+
android: 'c++';
|
|
63
|
+
}> {
|
|
64
|
+
abiVersion(): number;
|
|
65
|
+
workspaceBytes(): number;
|
|
66
|
+
attachGraph(memory: GraphMemory): NarsilAttachedGraph;
|
|
67
|
+
attachStore(memory: StoreMemory): NarsilAttachedStore;
|
|
68
|
+
search(graph: NarsilAttachedGraph, store: NarsilAttachedStore, query: MemoryView, metric: number, candidateCount: number, threadSlot: number, ordinals: MemoryView, distances: MemoryView, accepted: MemoryView, filtered: boolean): number;
|
|
69
|
+
searchAsync(graph: NarsilAttachedGraph, store: NarsilAttachedStore, query: MemoryView, metric: number, candidateCount: number, threadSlot: number, accepted: MemoryView, filtered: boolean): Promise<NativeSearchHits>;
|
|
70
|
+
scoreAsync(store: NarsilAttachedStore, query: MemoryView, metric: number, ordinals: MemoryView, count: number, threadSlot: number): Promise<NativeScores>;
|
|
71
|
+
score(store: NarsilAttachedStore, query: MemoryView, metric: number, ordinals: MemoryView, count: number, distances: MemoryView): number;
|
|
72
|
+
place(graph: NarsilAttachedGraph, store: NarsilAttachedStore, metric: number, ordinal: number, topLayer: number, graphHeldAlone: number, threadSlot: number, wakes: MemoryView): number;
|
|
73
|
+
remove(graph: NarsilAttachedGraph, ordinal: number, threadSlot: number, wakes: MemoryView): number;
|
|
74
|
+
compact(graph: NarsilAttachedGraph, store: NarsilAttachedStore, metric: number, threadSlot: number, wakes: MemoryView): number;
|
|
75
|
+
connectUnreached(graph: NarsilAttachedGraph, store: NarsilAttachedStore, metric: number, nearby: MemoryView, threadSlot: number, wakes: MemoryView): number;
|
|
76
|
+
connectUnreachedAsync(graph: NarsilAttachedGraph, store: NarsilAttachedStore, metric: number, nearby: MemoryView, threadSlot: number): Promise<NativeConnectOutcome>;
|
|
77
|
+
measure(store: NarsilAttachedStore, metric: number, ordinals: MemoryView, count: number, totals: MemoryView): number;
|
|
78
|
+
quantise(store: NarsilAttachedStore, metric: number, ordinals: MemoryView, count: number): number;
|
|
79
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { HybridObject } from 'react-native-nitro-modules';
|
|
2
|
+
export interface FileStatus {
|
|
3
|
+
size: number;
|
|
4
|
+
isDirectory: boolean;
|
|
5
|
+
isFile: boolean;
|
|
6
|
+
device: string;
|
|
7
|
+
inode: string;
|
|
8
|
+
modifiedMs: number;
|
|
9
|
+
}
|
|
10
|
+
export interface DirectoryEntry {
|
|
11
|
+
name: string;
|
|
12
|
+
isDirectory: boolean;
|
|
13
|
+
isFile: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface NarsilFiles extends HybridObject<{
|
|
16
|
+
ios: 'c++';
|
|
17
|
+
android: 'c++';
|
|
18
|
+
}> {
|
|
19
|
+
open(path: string, flags: string): number;
|
|
20
|
+
close(descriptor: number): void;
|
|
21
|
+
read(descriptor: number, target: ArrayBuffer, byteOffset: number, byteLength: number, position: number): number;
|
|
22
|
+
write(descriptor: number, source: ArrayBuffer, byteOffset: number, byteLength: number, position: number): number;
|
|
23
|
+
sync(descriptor: number): void;
|
|
24
|
+
readAsync(descriptor: number, byteLength: number, position: number): Promise<ArrayBuffer>;
|
|
25
|
+
writeAsync(descriptor: number, source: ArrayBuffer, byteOffset: number, byteLength: number, position: number): Promise<number>;
|
|
26
|
+
syncAsync(descriptor: number): Promise<void>;
|
|
27
|
+
truncate(descriptor: number, byteLength: number): void;
|
|
28
|
+
descriptorStatus(descriptor: number): FileStatus;
|
|
29
|
+
pathStatus(path: string): FileStatus;
|
|
30
|
+
makeDirectory(path: string): void;
|
|
31
|
+
readDirectory(path: string): DirectoryEntry[];
|
|
32
|
+
rename(from: string, to: string): void;
|
|
33
|
+
unlink(path: string): void;
|
|
34
|
+
removeDirectory(path: string): void;
|
|
35
|
+
link(existingPath: string, newPath: string): void;
|
|
36
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { HybridObject } from 'react-native-nitro-modules';
|
|
2
|
+
export interface ProcessMemory {
|
|
3
|
+
residentBytes: number;
|
|
4
|
+
availableBytes: number;
|
|
5
|
+
}
|
|
6
|
+
export interface NarsilHost extends HybridObject<{
|
|
7
|
+
ios: 'c++';
|
|
8
|
+
android: 'c++';
|
|
9
|
+
}> {
|
|
10
|
+
reserveMemory(bytes: number): ArrayBuffer;
|
|
11
|
+
allocateMemory(bytes: number): ArrayBuffer;
|
|
12
|
+
ownsMemory(buffer: ArrayBuffer): boolean;
|
|
13
|
+
atomic(operation: number, elementKind: number, buffer: ArrayBuffer, byteIndex: number, value: number, replacement: number): number;
|
|
14
|
+
fillRandom(target: ArrayBuffer, byteOffset: number, byteLength: number): void;
|
|
15
|
+
processId(): number;
|
|
16
|
+
processStartedAtMs(): number;
|
|
17
|
+
processIsAlive(processId: number): boolean;
|
|
18
|
+
processMemory(): ProcessMemory;
|
|
19
|
+
appStorageDirectory(): string;
|
|
20
|
+
deflateRaw(source: ArrayBuffer, byteOffset: number, byteLength: number): ArrayBuffer;
|
|
21
|
+
inflateRaw(source: ArrayBuffer, byteOffset: number, byteLength: number, rawByteLength: number): ArrayBuffer;
|
|
22
|
+
gzip(source: ArrayBuffer, byteOffset: number, byteLength: number): ArrayBuffer;
|
|
23
|
+
gunzip(source: ArrayBuffer, byteOffset: number, byteLength: number, maxByteLength: number): ArrayBuffer;
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface TransferredError {
|
|
2
|
+
transferredError: true;
|
|
3
|
+
name: string;
|
|
4
|
+
message: string;
|
|
5
|
+
code: string | undefined;
|
|
6
|
+
details: unknown;
|
|
7
|
+
}
|
|
8
|
+
export type CallOutcome = {
|
|
9
|
+
ok: true;
|
|
10
|
+
value: unknown;
|
|
11
|
+
} | {
|
|
12
|
+
ok: false;
|
|
13
|
+
error: TransferredError;
|
|
14
|
+
};
|
|
15
|
+
export declare function isTransferredError(value: unknown): value is TransferredError;
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import type { AnalysisChange, AnyDocument, BatchResult, BM25Params, DocumentImportResult, DurabilityConfig, IndexConfig, IndexInfo, IndexStats, InsertOptions, ListParams, ListResult, MemoryStats, NarsilConfig, NarsilEventMap, PartitionConfig, PartitionStatsResult, PreflightResult, QueryParams, QueryResult, SuggestParams, SuggestResult, SynonymRule, VectorMaintenanceResult, WriteOptions } from '@delali/narsil';
|
|
2
|
+
/**
|
|
3
|
+
* The engine settings, which are the settings of `createNarsil` in
|
|
4
|
+
* `@delali/narsil`, function settings such as `embeddingAdapters`, `plugins`,
|
|
5
|
+
* and `idGenerator` included.
|
|
6
|
+
*
|
|
7
|
+
* `durability` defaults to a write-ahead log in a `narsil` directory inside
|
|
8
|
+
* the app's private storage, and `null` keeps the index in memory alone. A
|
|
9
|
+
* relative `directory` resolves against that private storage.
|
|
10
|
+
*
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
export type PhoneNarsilConfig = Omit<NarsilConfig, 'durability'> & {
|
|
14
|
+
durability?: DurabilityConfig | null;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Receives one engine event on the app's JS thread. An `Error` inside the
|
|
18
|
+
* payload arrives as an `Error` carrying the original `name`, `message`,
|
|
19
|
+
* `code`, and `details`.
|
|
20
|
+
*
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
export type PhoneEventHandler<K extends keyof NarsilEventMap> = (payload: NarsilEventMap[K]) => void;
|
|
24
|
+
/**
|
|
25
|
+
* A Narsil engine on a phone. Every method resolves with the engine's answer,
|
|
26
|
+
* so a method that the engine answers synchronously, such as `listIndexes`,
|
|
27
|
+
* also resolves through a promise here. Each method otherwise behaves as the
|
|
28
|
+
* method of the same name on the `Narsil` interface of `@delali/narsil`.
|
|
29
|
+
*
|
|
30
|
+
* A failure rejects with an `Error` whose `name` is `NarsilError` for an
|
|
31
|
+
* engine failure, and whose `code` and `details` match the engine's error.
|
|
32
|
+
* {@link isNarsilError} recognises it.
|
|
33
|
+
*
|
|
34
|
+
* @public
|
|
35
|
+
*/
|
|
36
|
+
export interface PhoneNarsil {
|
|
37
|
+
/** Creates an index from a schema and its settings. */
|
|
38
|
+
createIndex(name: string, config: IndexConfig): Promise<void>;
|
|
39
|
+
/** Removes an index and the files that it wrote. */
|
|
40
|
+
dropIndex(name: string): Promise<void>;
|
|
41
|
+
/** Lists every index that this engine holds. */
|
|
42
|
+
listIndexes(): Promise<IndexInfo[]>;
|
|
43
|
+
/** Returns one index's document count, memory estimate, and schema. */
|
|
44
|
+
getStats(indexName: string): Promise<IndexStats>;
|
|
45
|
+
/** Returns the figures of each open partition of one index. */
|
|
46
|
+
getPartitionStats(indexName: string): Promise<PartitionStatsResult[]>;
|
|
47
|
+
/** Fetches one stored document by id, or `undefined` when the index lacks it. */
|
|
48
|
+
get(indexName: string, docId: string): Promise<AnyDocument | undefined>;
|
|
49
|
+
/** Fetches many stored documents by id, keyed by id. */
|
|
50
|
+
getMultiple(indexName: string, docIds: string[]): Promise<Map<string, AnyDocument>>;
|
|
51
|
+
/** Reports whether an index holds a document. */
|
|
52
|
+
has(indexName: string, docId: string): Promise<boolean>;
|
|
53
|
+
/** Counts the documents of one index. */
|
|
54
|
+
countDocuments(indexName: string): Promise<number>;
|
|
55
|
+
/** Reads one page of stored documents in document-id order. */
|
|
56
|
+
listDocuments<T = AnyDocument>(indexName: string, params?: ListParams): Promise<ListResult<T>>;
|
|
57
|
+
/** Searches one index by keyword, by vector, or by both. */
|
|
58
|
+
query<T = AnyDocument>(indexName: string, params: QueryParams): Promise<QueryResult<T>>;
|
|
59
|
+
/** Counts what a query would match without building a single hit. */
|
|
60
|
+
preflight(indexName: string, params: QueryParams): Promise<PreflightResult>;
|
|
61
|
+
/** Returns the indexed terms that complete a prefix. */
|
|
62
|
+
suggest(indexName: string, params: SuggestParams): Promise<SuggestResult>;
|
|
63
|
+
/** Rebuilds an index's terms from the documents that it already stores. */
|
|
64
|
+
rebuildAnalysis(indexName: string): Promise<void>;
|
|
65
|
+
/** Returns a snapshot of one index as the bytes of one `.nrsl` file. */
|
|
66
|
+
snapshot(indexName: string): Promise<Uint8Array>;
|
|
67
|
+
/**
|
|
68
|
+
* Writes a snapshot of one index into a file and resolves with its size in
|
|
69
|
+
* bytes. A relative path resolves against the app's private storage, and
|
|
70
|
+
* the file replaces any file at that path only once every byte is on disk.
|
|
71
|
+
*/
|
|
72
|
+
snapshotToFile(indexName: string, path: string): Promise<number>;
|
|
73
|
+
/** Replaces one index with the snapshot in these bytes. */
|
|
74
|
+
restore(indexName: string, data: Uint8Array): Promise<void>;
|
|
75
|
+
/** Replaces one index with the snapshot in a file, which the engine reads in chunks. */
|
|
76
|
+
restoreFromFile(indexName: string, path: string): Promise<void>;
|
|
77
|
+
/** Returns every document of one index as the bytes of a document export. */
|
|
78
|
+
exportDocuments(indexName: string): Promise<Uint8Array>;
|
|
79
|
+
/** Writes a document export of one index into a file and resolves with its size in bytes. */
|
|
80
|
+
exportDocumentsToFile(indexName: string, path: string): Promise<number>;
|
|
81
|
+
/** Inserts the documents of a document export held in these bytes. */
|
|
82
|
+
importDocumentExport(indexName: string, data: Uint8Array): Promise<DocumentImportResult>;
|
|
83
|
+
/** Inserts the documents of a document export held in a file. */
|
|
84
|
+
importDocumentExportFromFile(indexName: string, path: string): Promise<DocumentImportResult>;
|
|
85
|
+
/** Writes an index's current state to the durability directory, so a restart replays less of the log. */
|
|
86
|
+
checkpoint(indexName: string): Promise<void>;
|
|
87
|
+
/** Removes every document from an index and keeps the index, its schema, and its settings. */
|
|
88
|
+
clear(indexName: string): Promise<void>;
|
|
89
|
+
/** Spreads an index's documents across a different number of partitions. */
|
|
90
|
+
rebalance(indexName: string, targetPartitionCount: number): Promise<void>;
|
|
91
|
+
/** Changes how an index grows into new partitions. */
|
|
92
|
+
updatePartitionConfig(indexName: string, config: Partial<PartitionConfig>): Promise<void>;
|
|
93
|
+
/** Reports what this engine and the app's process use. */
|
|
94
|
+
getMemoryStats(): Promise<MemoryStats>;
|
|
95
|
+
/** Rebuilds a vector field's graph without the tombstones that removed documents left behind. */
|
|
96
|
+
compactVectors(indexName: string, fieldName?: string): Promise<void>;
|
|
97
|
+
/** Rebuilds a vector field's graph from scratch, which recovers recall. */
|
|
98
|
+
optimizeVectors(indexName: string, fieldName?: string): Promise<void>;
|
|
99
|
+
/** Reports the state of each vector field in an index, and what its maintenance would cost. */
|
|
100
|
+
vectorMaintenanceStatus(indexName: string): Promise<VectorMaintenanceResult[]>;
|
|
101
|
+
/** Opens a closed index. */
|
|
102
|
+
open(indexName: string): Promise<void>;
|
|
103
|
+
/** Closes an index. */
|
|
104
|
+
close(indexName: string): Promise<void>;
|
|
105
|
+
/** Inserts one document and resolves with the id that it is stored under. */
|
|
106
|
+
insert(indexName: string, document: AnyDocument, docId?: string, options?: InsertOptions): Promise<string>;
|
|
107
|
+
/** Inserts many documents in one request. */
|
|
108
|
+
insertBatch(indexName: string, documents: AnyDocument[], options?: InsertOptions): Promise<BatchResult>;
|
|
109
|
+
/** Removes one document. */
|
|
110
|
+
remove(indexName: string, docId: string, options?: WriteOptions): Promise<void>;
|
|
111
|
+
/** Removes many documents in one request. */
|
|
112
|
+
removeBatch(indexName: string, docIds: string[], options?: WriteOptions): Promise<BatchResult>;
|
|
113
|
+
/** Replaces one stored document. */
|
|
114
|
+
update(indexName: string, docId: string, document: AnyDocument, options?: WriteOptions): Promise<void>;
|
|
115
|
+
/** Replaces many stored documents in one request. */
|
|
116
|
+
updateBatch(indexName: string, updates: Array<{
|
|
117
|
+
docId: string;
|
|
118
|
+
document: AnyDocument;
|
|
119
|
+
}>, options?: WriteOptions): Promise<BatchResult>;
|
|
120
|
+
/** Resolves once every worker copy of an index has applied every earlier write. */
|
|
121
|
+
waitForWrites(indexName: string): Promise<void>;
|
|
122
|
+
/** Replaces the synonym rules of one index. */
|
|
123
|
+
updateSynonyms(indexName: string, synonyms: SynonymRule[]): Promise<void>;
|
|
124
|
+
/** Returns the synonym rules of one index. */
|
|
125
|
+
getSynonyms(indexName: string): Promise<SynonymRule[]>;
|
|
126
|
+
/** Changes how one index analyses text, and re-analyses its documents. */
|
|
127
|
+
changeAnalysis(indexName: string, change: AnalysisChange): Promise<void>;
|
|
128
|
+
/** Changes the BM25 parameters of one index. */
|
|
129
|
+
updateBM25(indexName: string, bm25: BM25Params): Promise<void>;
|
|
130
|
+
/** Calls a handler on the app's JS thread for each engine event of one kind. */
|
|
131
|
+
on<K extends keyof NarsilEventMap>(event: K, handler: PhoneEventHandler<K>): void;
|
|
132
|
+
/** Stops calling a handler that {@link PhoneNarsil.on} registered. */
|
|
133
|
+
off<K extends keyof NarsilEventMap>(event: K, handler: PhoneEventHandler<K>): void;
|
|
134
|
+
/** Shuts the engine down, after which every other method rejects with `INSTANCE_SHUT_DOWN`. */
|
|
135
|
+
shutdown(): Promise<void>;
|
|
136
|
+
}
|
package/lib/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function afterAppTurn(run: () => void): void;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { APP_TIMER_WAIT_BEFORE_RUN_LOOP_HOP_MS } from '../constants';
|
|
2
|
+
function hopThroughRuntimeScheduler() {
|
|
3
|
+
const runtimeScheduler = Reflect.get(globalThis, 'nativeRuntimeScheduler');
|
|
4
|
+
if (typeof runtimeScheduler !== 'object' || runtimeScheduler === null)
|
|
5
|
+
return null;
|
|
6
|
+
const schedule = Reflect.get(runtimeScheduler, 'unstable_scheduleCallback');
|
|
7
|
+
const priority = Reflect.get(runtimeScheduler, 'unstable_NormalPriority');
|
|
8
|
+
if (typeof schedule !== 'function' || typeof priority !== 'number')
|
|
9
|
+
return null;
|
|
10
|
+
let appTimerArmedAt = null;
|
|
11
|
+
let runsAfterAppTimer = [];
|
|
12
|
+
function appTimerFired() {
|
|
13
|
+
appTimerArmedAt = null;
|
|
14
|
+
const runs = runsAfterAppTimer;
|
|
15
|
+
runsAfterAppTimer = [];
|
|
16
|
+
for (const run of runs)
|
|
17
|
+
run();
|
|
18
|
+
}
|
|
19
|
+
return run => {
|
|
20
|
+
const now = performance.now();
|
|
21
|
+
if (appTimerArmedAt === null) {
|
|
22
|
+
appTimerArmedAt = now;
|
|
23
|
+
setTimeout(appTimerFired, 0);
|
|
24
|
+
}
|
|
25
|
+
else if (now - appTimerArmedAt >= APP_TIMER_WAIT_BEFORE_RUN_LOOP_HOP_MS) {
|
|
26
|
+
runsAfterAppTimer.push(run);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
Reflect.apply(schedule, runtimeScheduler, [
|
|
30
|
+
priority,
|
|
31
|
+
() => {
|
|
32
|
+
run();
|
|
33
|
+
},
|
|
34
|
+
]);
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function hopThroughTimer(run) {
|
|
38
|
+
setTimeout(run, 0);
|
|
39
|
+
}
|
|
40
|
+
let hop = null;
|
|
41
|
+
export function afterAppTurn(run) {
|
|
42
|
+
hop ??= hopThroughRuntimeScheduler() ?? hopThroughTimer;
|
|
43
|
+
hop(run);
|
|
44
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { PhoneNarsil } from '../types';
|
|
2
|
+
import type { EngineSetup, WorkletNarsilConfig } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Starts a Narsil engine on its own Worklets runtime and resolves with a
|
|
5
|
+
* client whose methods send each request to that runtime, so the engine's
|
|
6
|
+
* JavaScript work leaves the app's JS thread free. Every engine that this
|
|
7
|
+
* function starts shares one runtime, and each engine keeps its own indexes.
|
|
8
|
+
* The app needs `react-native-worklets` with Bundle Mode turned on. The
|
|
9
|
+
* client copies each batch that an insert sends across to the engine's
|
|
10
|
+
* runtime before the engine indexes it, as JSON text when the batch holds
|
|
11
|
+
* plain data. On a physical iPhone and a physical Android phone, inserts took
|
|
12
|
+
* 6% to 57% longer than on the app's own JS runtime, depending on the number
|
|
13
|
+
* of documents and on durability, and an import from a file, which sends only
|
|
14
|
+
* the file's path across, took up to 11% longer. In return, the longest pause
|
|
15
|
+
* that a 10 ms timer on the app's JS thread saw during an insert of 50,000
|
|
16
|
+
* documents fell from 111 ms to 30 ms on the Android phone and from 144 ms to
|
|
17
|
+
* 74 ms on the iPhone.
|
|
18
|
+
*
|
|
19
|
+
* @param config - The engine settings that cross to the engine's runtime as
|
|
20
|
+
* data. `durability` defaults to a write-ahead log in the `narsil` directory
|
|
21
|
+
* of the app's private storage.
|
|
22
|
+
* @param setup - A worklet that returns the settings that hold functions,
|
|
23
|
+
* such as embedding adapters, plugins, or an id generator.
|
|
24
|
+
* @returns The client, once the engine has started on its runtime.
|
|
25
|
+
* @throws A `NarsilError` with `NATIVE_DEPENDENCY_MISSING` when the app's
|
|
26
|
+
* build lacks the native module, as in Expo Go.
|
|
27
|
+
*
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export declare function createNarsil(config?: WorkletNarsilConfig, setup?: EngineSetup): Promise<PhoneNarsil>;
|