react-native-jieba 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/Jieba.podspec +2 -0
  3. package/README.md +118 -7
  4. package/android/CMakeLists.txt +2 -0
  5. package/android/generated/java/com/jieba/NativeJiebaSpec.java +4 -0
  6. package/android/generated/jni/JiebaSpec-generated.cpp +6 -0
  7. package/android/generated/jni/react/renderer/components/JiebaSpec/JiebaSpecJSI.h +8 -0
  8. package/android/src/main/java/com/jieba/JiebaAndroidHelperModule.kt +7 -22
  9. package/android/src/main/java/com/jieba/JiebaDict.kt +72 -0
  10. package/android/src/main/java/com/jieba/JiebaPackage.kt +4 -0
  11. package/cpp/JiebaDictAndroid.cpp +26 -0
  12. package/cpp/JiebaDictAndroid.h +14 -0
  13. package/cpp/JiebaImpl.cpp +23 -0
  14. package/cpp/JiebaImpl.h +1 -0
  15. package/cpp/cppjieba/CHANGELOG.md +18 -0
  16. package/cpp/cppjieba/README.md +288 -0
  17. package/cpp/cppjieba/deps/limonp/CHANGELOG.md +175 -0
  18. package/cpp/cppjieba/deps/limonp/README.md +43 -0
  19. package/cpp/cppjieba/dict/README.md +62 -0
  20. package/ios/generated/ReactCodegen/JiebaSpec/JiebaSpec-generated.mm +7 -0
  21. package/ios/generated/ReactCodegen/JiebaSpec/JiebaSpec.h +1 -0
  22. package/ios/generated/ReactCodegen/JiebaSpecJSI.h +8 -0
  23. package/lib/module/NativeJieba.js.map +1 -1
  24. package/lib/module/NativeJieba.web.js +66 -0
  25. package/lib/module/NativeJieba.web.js.map +1 -0
  26. package/lib/module/index.js +1 -1
  27. package/lib/module/index.js.map +1 -1
  28. package/lib/module/init.js +34 -7
  29. package/lib/module/init.js.map +1 -1
  30. package/lib/module/init.web.js +40 -0
  31. package/lib/module/init.web.js.map +1 -0
  32. package/lib/module/jieba.js +1 -1
  33. package/lib/module/jieba.js.map +1 -1
  34. package/lib/typescript/src/NativeJieba.d.ts +1 -0
  35. package/lib/typescript/src/NativeJieba.d.ts.map +1 -1
  36. package/lib/typescript/src/NativeJieba.web.d.ts +16 -0
  37. package/lib/typescript/src/NativeJieba.web.d.ts.map +1 -0
  38. package/lib/typescript/src/index.d.ts +2 -1
  39. package/lib/typescript/src/index.d.ts.map +1 -1
  40. package/lib/typescript/src/init.d.ts +32 -1
  41. package/lib/typescript/src/init.d.ts.map +1 -1
  42. package/lib/typescript/src/init.web.d.ts +18 -0
  43. package/lib/typescript/src/init.web.d.ts.map +1 -0
  44. package/lib/typescript/src/jieba.d.ts.map +1 -1
  45. package/package.json +13 -1
  46. package/src/NativeJieba.ts +1 -0
  47. package/src/NativeJieba.web.ts +90 -0
  48. package/src/index.tsx +2 -1
  49. package/src/init.ts +43 -6
  50. package/src/init.web.ts +53 -0
  51. package/src/jieba.ts +1 -4
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+
3
+ // `jieba-wasm` exposes the same segmentation primitives as cppjieba, but a
4
+ // smaller surface: cut / cutAll / cutForSearch / tag / add_word. The remaining
5
+ // native methods are polyfilled on top of those where the semantics allow, and
6
+ // throw otherwise. The wasm module is loaded lazily by `prepareJieba()` (see
7
+ // `init.web.ts`) and handed to this shim via `setJiebaWasm`.
8
+
9
+ let wasm = null;
10
+ export function setJiebaWasm(module) {
11
+ wasm = module;
12
+ }
13
+ export function isJiebaWasmReady() {
14
+ return wasm !== null;
15
+ }
16
+ function getWasm() {
17
+ if (!wasm) {
18
+ throw new Error('react-native-jieba: jieba-wasm is not loaded yet. ' + 'On web you must call (and await) prepareJieba() before any ' + 'segmentation call.');
19
+ }
20
+ return wasm;
21
+ }
22
+ const Jieba = {
23
+ isReady() {
24
+ return isJiebaWasmReady();
25
+ },
26
+ setDictPath() {
27
+ // No-op on web: jieba-wasm bundles its own dictionary.
28
+ },
29
+ cut(sentence, hmm) {
30
+ return getWasm().cut(sentence, hmm);
31
+ },
32
+ cutAll(sentence) {
33
+ return getWasm().cut_all(sentence);
34
+ },
35
+ cutForSearch(sentence, hmm) {
36
+ return getWasm().cut_for_search(sentence, hmm);
37
+ },
38
+ cutHMM(sentence) {
39
+ // jieba-wasm has no HMM-only mode; precise cut with HMM enabled is the
40
+ // closest equivalent.
41
+ return getWasm().cut(sentence, true);
42
+ },
43
+ cutSmall(sentence, _maxWordLen) {
44
+ // jieba-wasm does not expose a max-word-length cut; fall back to precise
45
+ // cut. The maxWordLen argument is accepted for API parity but ignored.
46
+ return getWasm().cut(sentence, true);
47
+ },
48
+ tag(sentence) {
49
+ return getWasm().tag(sentence);
50
+ },
51
+ extract() {
52
+ throw new Error('react-native-jieba: extract() (TF-IDF keyword extraction) is not ' + 'supported on web — jieba-wasm does not ship the IDF dictionary.');
53
+ },
54
+ insertUserWord(word, tag) {
55
+ // add_word returns the inserted word's frequency (>= 0 on success).
56
+ return getWasm().add_word(word, undefined, tag === '' ? undefined : tag) >= 0;
57
+ },
58
+ find(word) {
59
+ // jieba-wasm has no dictionary lookup; approximate it by checking whether
60
+ // the word survives precise (non-HMM) segmentation as a single token.
61
+ const segments = getWasm().cut(word, false);
62
+ return segments.length === 1 && segments[0] === word;
63
+ }
64
+ };
65
+ export default Jieba;
66
+ //# sourceMappingURL=NativeJieba.web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["wasm","setJiebaWasm","module","isJiebaWasmReady","getWasm","Error","Jieba","isReady","setDictPath","cut","sentence","hmm","cutAll","cut_all","cutForSearch","cut_for_search","cutHMM","cutSmall","_maxWordLen","tag","extract","insertUserWord","word","add_word","undefined","find","segments","length"],"sourceRoot":"../../src","sources":["NativeJieba.web.ts"],"mappings":";;AAEA;AACA;AACA;AACA;AACA;;AAaA,IAAIA,IAA4B,GAAG,IAAI;AAEvC,OAAO,SAASC,YAAYA,CAACC,MAAuB,EAAQ;EAC1DF,IAAI,GAAGE,MAAM;AACf;AAEA,OAAO,SAASC,gBAAgBA,CAAA,EAAY;EAC1C,OAAOH,IAAI,KAAK,IAAI;AACtB;AAEA,SAASI,OAAOA,CAAA,EAAoB;EAClC,IAAI,CAACJ,IAAI,EAAE;IACT,MAAM,IAAIK,KAAK,CACb,oDAAoD,GAClD,6DAA6D,GAC7D,oBACJ,CAAC;EACH;EACA,OAAOL,IAAI;AACb;AAEA,MAAMM,KAAW,GAAG;EAClBC,OAAOA,CAAA,EAAG;IACR,OAAOJ,gBAAgB,CAAC,CAAC;EAC3B,CAAC;EACDK,WAAWA,CAAA,EAAG;IACZ;EAAA,CACD;EACDC,GAAGA,CAACC,QAAQ,EAAEC,GAAG,EAAE;IACjB,OAAOP,OAAO,CAAC,CAAC,CAACK,GAAG,CAACC,QAAQ,EAAEC,GAAG,CAAC;EACrC,CAAC;EACDC,MAAMA,CAACF,QAAQ,EAAE;IACf,OAAON,OAAO,CAAC,CAAC,CAACS,OAAO,CAACH,QAAQ,CAAC;EACpC,CAAC;EACDI,YAAYA,CAACJ,QAAQ,EAAEC,GAAG,EAAE;IAC1B,OAAOP,OAAO,CAAC,CAAC,CAACW,cAAc,CAACL,QAAQ,EAAEC,GAAG,CAAC;EAChD,CAAC;EACDK,MAAMA,CAACN,QAAQ,EAAE;IACf;IACA;IACA,OAAON,OAAO,CAAC,CAAC,CAACK,GAAG,CAACC,QAAQ,EAAE,IAAI,CAAC;EACtC,CAAC;EACDO,QAAQA,CAACP,QAAQ,EAAEQ,WAAW,EAAE;IAC9B;IACA;IACA,OAAOd,OAAO,CAAC,CAAC,CAACK,GAAG,CAACC,QAAQ,EAAE,IAAI,CAAC;EACtC,CAAC;EACDS,GAAGA,CAACT,QAAQ,EAAE;IACZ,OAAON,OAAO,CAAC,CAAC,CAACe,GAAG,CAACT,QAAQ,CAAC;EAChC,CAAC;EACDU,OAAOA,CAAA,EAAG;IACR,MAAM,IAAIf,KAAK,CACb,mEAAmE,GACjE,iEACJ,CAAC;EACH,CAAC;EACDgB,cAAcA,CAACC,IAAI,EAAEH,GAAG,EAAE;IACxB;IACA,OACEf,OAAO,CAAC,CAAC,CAACmB,QAAQ,CAACD,IAAI,EAAEE,SAAS,EAAEL,GAAG,KAAK,EAAE,GAAGK,SAAS,GAAGL,GAAG,CAAC,IAAI,CAAC;EAE1E,CAAC;EACDM,IAAIA,CAACH,IAAI,EAAE;IACT;IACA;IACA,MAAMI,QAAQ,GAAGtB,OAAO,CAAC,CAAC,CAACK,GAAG,CAACa,IAAI,EAAE,KAAK,CAAC;IAC3C,OAAOI,QAAQ,CAACC,MAAM,KAAK,CAAC,IAAID,QAAQ,CAAC,CAAC,CAAC,KAAKJ,IAAI;EACtD;AACF,CAAC;AAED,eAAehB,KAAK","ignoreList":[]}
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
 
3
3
  export { cut, cutAll, cutForSearch, cutHMM, cutSmall, tag, extract, insertUserWord, find } from "./jieba.js";
4
- export { initJieba } from "./init.js";
4
+ export { prepareJieba, isJiebaReady } from './init';
5
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["cut","cutAll","cutForSearch","cutHMM","cutSmall","tag","extract","insertUserWord","find","initJieba"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SACEA,GAAG,EACHC,MAAM,EACNC,YAAY,EACZC,MAAM,EACNC,QAAQ,EACRC,GAAG,EACHC,OAAO,EACPC,cAAc,EACdC,IAAI,QACC,YAAS;AAEhB,SAASC,SAAS,QAAQ,WAAQ","ignoreList":[]}
1
+ {"version":3,"names":["cut","cutAll","cutForSearch","cutHMM","cutSmall","tag","extract","insertUserWord","find","prepareJieba","isJiebaReady"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SACEA,GAAG,EACHC,MAAM,EACNC,YAAY,EACZC,MAAM,EACNC,QAAQ,EACRC,GAAG,EACHC,OAAO,EACPC,cAAc,EACdC,IAAI,QACC,YAAS;AAEhB,SAASC,YAAY,EAAEC,YAAY,QAAQ,QAAQ","ignoreList":[]}
@@ -1,12 +1,28 @@
1
1
  "use strict";
2
2
 
3
3
  import { Platform } from 'react-native';
4
- import Jieba from "./NativeJieba.js";
4
+ import Jieba from './NativeJieba';
5
5
  import JiebaAndroidHelper from "./NativeJiebaAndroidHelper.js";
6
- let initPromise = null;
7
- export function initJieba() {
8
- if (initPromise) return initPromise;
9
- initPromise = (async () => {
6
+ let preparePromise = null;
7
+
8
+ /**
9
+ * Optional on native (iOS/Android): the dictionary is located/extracted
10
+ * automatically on the first segmentation call, so you can call `cut`, `tag`,
11
+ * etc. directly without ever calling `prepareJieba`.
12
+ *
13
+ * Calling it is still useful as a *warm-up*: on Android's very first run the
14
+ * dictionary assets are extracted from the APK, and doing that work here
15
+ * (asynchronously, up front) avoids a one-time blocking pause on the first
16
+ * `cut`/`tag` call.
17
+ *
18
+ * On web it is **required** — it loads and instantiates the `jieba-wasm`
19
+ * binary, which cannot be done synchronously.
20
+ *
21
+ * Idempotent: repeated calls return the same promise.
22
+ */
23
+ export function prepareJieba(_options = {}) {
24
+ if (preparePromise) return preparePromise;
25
+ preparePromise = (async () => {
10
26
  if (Platform.OS === 'android') {
11
27
  if (!JiebaAndroidHelper) {
12
28
  throw new Error('react-native-jieba: JiebaAndroidHelper native module is missing.');
@@ -16,9 +32,20 @@ export function initJieba() {
16
32
  }
17
33
  // iOS: OnLoad.mm already configured the dict path from the bundle.
18
34
  })().catch(err => {
19
- initPromise = null;
35
+ preparePromise = null;
20
36
  throw err;
21
37
  });
22
- return initPromise;
38
+ return preparePromise;
39
+ }
40
+
41
+ /**
42
+ * Whether jieba is ready to segment synchronously.
43
+ *
44
+ * Backed by the native engine state (not by whether `prepareJieba` was called),
45
+ * so it stays correct even when the dictionary is resolved lazily on the first
46
+ * `cut`/`tag` call. On iOS this is `true` from app launch.
47
+ */
48
+ export function isJiebaReady() {
49
+ return Jieba.isReady();
23
50
  }
24
51
  //# sourceMappingURL=init.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["Platform","Jieba","JiebaAndroidHelper","initPromise","initJieba","OS","Error","path","prepareDictDir","setDictPath","catch","err"],"sourceRoot":"../../src","sources":["init.ts"],"mappings":";;AAAA,SAASA,QAAQ,QAAQ,cAAc;AACvC,OAAOC,KAAK,MAAM,kBAAe;AACjC,OAAOC,kBAAkB,MAAM,+BAA4B;AAE3D,IAAIC,WAAiC,GAAG,IAAI;AAE5C,OAAO,SAASC,SAASA,CAAA,EAAkB;EACzC,IAAID,WAAW,EAAE,OAAOA,WAAW;EACnCA,WAAW,GAAG,CAAC,YAAY;IACzB,IAAIH,QAAQ,CAACK,EAAE,KAAK,SAAS,EAAE;MAC7B,IAAI,CAACH,kBAAkB,EAAE;QACvB,MAAM,IAAII,KAAK,CACb,kEACF,CAAC;MACH;MACA,MAAMC,IAAI,GAAG,MAAML,kBAAkB,CAACM,cAAc,CAAC,CAAC;MACtDP,KAAK,CAACQ,WAAW,CAACF,IAAI,CAAC;IACzB;IACA;EACF,CAAC,EAAE,CAAC,CAACG,KAAK,CAAEC,GAAG,IAAK;IAClBR,WAAW,GAAG,IAAI;IAClB,MAAMQ,GAAG;EACX,CAAC,CAAC;EACF,OAAOR,WAAW;AACpB","ignoreList":[]}
1
+ {"version":3,"names":["Platform","Jieba","JiebaAndroidHelper","preparePromise","prepareJieba","_options","OS","Error","path","prepareDictDir","setDictPath","catch","err","isJiebaReady","isReady"],"sourceRoot":"../../src","sources":["init.ts"],"mappings":";;AAAA,SAASA,QAAQ,QAAQ,cAAc;AACvC,OAAOC,KAAK,MAAM,eAAe;AACjC,OAAOC,kBAAkB,MAAM,+BAA4B;AAW3D,IAAIC,cAAoC,GAAG,IAAI;;AAE/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,YAAYA,CAC1BC,QAA6B,GAAG,CAAC,CAAC,EACnB;EACf,IAAIF,cAAc,EAAE,OAAOA,cAAc;EACzCA,cAAc,GAAG,CAAC,YAAY;IAC5B,IAAIH,QAAQ,CAACM,EAAE,KAAK,SAAS,EAAE;MAC7B,IAAI,CAACJ,kBAAkB,EAAE;QACvB,MAAM,IAAIK,KAAK,CACb,kEACF,CAAC;MACH;MACA,MAAMC,IAAI,GAAG,MAAMN,kBAAkB,CAACO,cAAc,CAAC,CAAC;MACtDR,KAAK,CAACS,WAAW,CAACF,IAAI,CAAC;IACzB;IACA;EACF,CAAC,EAAE,CAAC,CAACG,KAAK,CAAEC,GAAG,IAAK;IAClBT,cAAc,GAAG,IAAI;IACrB,MAAMS,GAAG;EACX,CAAC,CAAC;EACF,OAAOT,cAAc;AACvB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASU,YAAYA,CAAA,EAAY;EACtC,OAAOZ,KAAK,CAACa,OAAO,CAAC,CAAC;AACxB","ignoreList":[]}
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+
3
+ import { setJiebaWasm, isJiebaWasmReady } from "./NativeJieba.web.js";
4
+ let preparePromise = null;
5
+
6
+ /**
7
+ * **Required on web**: loads and instantiates the `jieba-wasm` binary (which
8
+ * cannot be done synchronously). Await it once before calling `cut`, `tag`, etc.
9
+ *
10
+ * Idempotent: repeated calls return the same promise.
11
+ */
12
+ export function prepareJieba(options = {}) {
13
+ if (preparePromise) return preparePromise;
14
+ preparePromise = (async () => {
15
+ // `jieba-wasm` resolves to its `web` build under the `browser`/`import`
16
+ // conditions, whose default export is an async initializer that fetches
17
+ // and instantiates the wasm binary.
18
+ const wasm = await import('jieba-wasm');
19
+
20
+ // With no argument, jieba-wasm's `web` initializer resolves the binary via
21
+ // `new URL('jieba_rs_wasm_bg.wasm', import.meta.url)` *relative to its own
22
+ // module*, which bundlers (Vite, Webpack 5, …) rewrite to the correct
23
+ // emitted asset URL in both dev and production. Only pass `wasmUrl` when the
24
+ // consumer explicitly overrides where the binary is served from — passing a
25
+ // wrong/relative path here makes the dev server return index.html and wasm
26
+ // instantiation fails with a bad magic word.
27
+ await wasm.default(options.wasmUrl);
28
+ setJiebaWasm(wasm);
29
+ })().catch(err => {
30
+ preparePromise = null;
31
+ throw err;
32
+ });
33
+ return preparePromise;
34
+ }
35
+
36
+ /** Whether the wasm module has been loaded and jieba can segment. */
37
+ export function isJiebaReady() {
38
+ return isJiebaWasmReady();
39
+ }
40
+ //# sourceMappingURL=init.web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["setJiebaWasm","isJiebaWasmReady","preparePromise","prepareJieba","options","wasm","default","wasmUrl","catch","err","isJiebaReady"],"sourceRoot":"../../src","sources":["init.web.ts"],"mappings":";;AAAA,SACEA,YAAY,EACZC,gBAAgB,QAEX,sBAAmB;AAW1B,IAAIC,cAAoC,GAAG,IAAI;;AAE/C;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,YAAYA,CAACC,OAA4B,GAAG,CAAC,CAAC,EAAiB;EAC7E,IAAIF,cAAc,EAAE,OAAOA,cAAc;EACzCA,cAAc,GAAG,CAAC,YAAY;IAC5B;IACA;IACA;IACA,MAAMG,IAAI,GAAI,MAAM,MAAM,CAAC,YAAY,CAEpB;;IAEnB;IACA;IACA;IACA;IACA;IACA;IACA;IACA,MAAMA,IAAI,CAACC,OAAO,CAACF,OAAO,CAACG,OAAO,CAAC;IACnCP,YAAY,CAACK,IAAI,CAAC;EACpB,CAAC,EAAE,CAAC,CAACG,KAAK,CAAEC,GAAG,IAAK;IAClBP,cAAc,GAAG,IAAI;IACrB,MAAMO,GAAG;EACX,CAAC,CAAC;EACF,OAAOP,cAAc;AACvB;;AAEA;AACA,OAAO,SAASQ,YAAYA,CAAA,EAAY;EACtC,OAAOT,gBAAgB,CAAC,CAAC;AAC3B","ignoreList":[]}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- import Jieba from "./NativeJieba.js";
3
+ import Jieba from './NativeJieba';
4
4
  export function cut(sentence, hmm = true) {
5
5
  return Jieba.cut(sentence, hmm);
6
6
  }
@@ -1 +1 @@
1
- {"version":3,"names":["Jieba","cut","sentence","hmm","cutAll","cutForSearch","cutHMM","cutSmall","maxWordLen","tag","extract","topK","insertUserWord","word","find"],"sourceRoot":"../../src","sources":["jieba.ts"],"mappings":";;AAAA,OAAOA,KAAK,MAAM,kBAAe;AAKjC,OAAO,SAASC,GAAGA,CAACC,QAAgB,EAAEC,GAAY,GAAG,IAAI,EAAY;EACnE,OAAOH,KAAK,CAACC,GAAG,CAACC,QAAQ,EAAEC,GAAG,CAAC;AACjC;AAEA,OAAO,SAASC,MAAMA,CAACF,QAAgB,EAAY;EACjD,OAAOF,KAAK,CAACI,MAAM,CAACF,QAAQ,CAAC;AAC/B;AAEA,OAAO,SAASG,YAAYA,CAC1BH,QAAgB,EAChBC,GAAY,GAAG,IAAI,EACT;EACV,OAAOH,KAAK,CAACK,YAAY,CAACH,QAAQ,EAAEC,GAAG,CAAC;AAC1C;AAEA,OAAO,SAASG,MAAMA,CAACJ,QAAgB,EAAY;EACjD,OAAOF,KAAK,CAACM,MAAM,CAACJ,QAAQ,CAAC;AAC/B;AAEA,OAAO,SAASK,QAAQA,CAACL,QAAgB,EAAEM,UAAkB,EAAY;EACvE,OAAOR,KAAK,CAACO,QAAQ,CAACL,QAAQ,EAAEM,UAAU,CAAC;AAC7C;AAEA,OAAO,SAASC,GAAGA,CAACP,QAAgB,EAAY;EAC9C,OAAOF,KAAK,CAACS,GAAG,CAACP,QAAQ,CAAC;AAC5B;AAEA,OAAO,SAASQ,OAAOA,CAACR,QAAgB,EAAES,IAAY,GAAG,CAAC,EAAa;EACrE,OAAOX,KAAK,CAACU,OAAO,CAACR,QAAQ,EAAES,IAAI,CAAC;AACtC;AAEA,OAAO,SAASC,cAAcA,CAACC,IAAY,EAAEJ,GAAW,GAAG,EAAE,EAAW;EACtE,OAAOT,KAAK,CAACY,cAAc,CAACC,IAAI,EAAEJ,GAAG,CAAC;AACxC;AAEA,OAAO,SAASK,IAAIA,CAACD,IAAY,EAAW;EAC1C,OAAOb,KAAK,CAACc,IAAI,CAACD,IAAI,CAAC;AACzB","ignoreList":[]}
1
+ {"version":3,"names":["Jieba","cut","sentence","hmm","cutAll","cutForSearch","cutHMM","cutSmall","maxWordLen","tag","extract","topK","insertUserWord","word","find"],"sourceRoot":"../../src","sources":["jieba.ts"],"mappings":";;AAAA,OAAOA,KAAK,MAAM,eAAe;AAKjC,OAAO,SAASC,GAAGA,CAACC,QAAgB,EAAEC,GAAY,GAAG,IAAI,EAAY;EACnE,OAAOH,KAAK,CAACC,GAAG,CAACC,QAAQ,EAAEC,GAAG,CAAC;AACjC;AAEA,OAAO,SAASC,MAAMA,CAACF,QAAgB,EAAY;EACjD,OAAOF,KAAK,CAACI,MAAM,CAACF,QAAQ,CAAC;AAC/B;AAEA,OAAO,SAASG,YAAYA,CAACH,QAAgB,EAAEC,GAAY,GAAG,IAAI,EAAY;EAC5E,OAAOH,KAAK,CAACK,YAAY,CAACH,QAAQ,EAAEC,GAAG,CAAC;AAC1C;AAEA,OAAO,SAASG,MAAMA,CAACJ,QAAgB,EAAY;EACjD,OAAOF,KAAK,CAACM,MAAM,CAACJ,QAAQ,CAAC;AAC/B;AAEA,OAAO,SAASK,QAAQA,CAACL,QAAgB,EAAEM,UAAkB,EAAY;EACvE,OAAOR,KAAK,CAACO,QAAQ,CAACL,QAAQ,EAAEM,UAAU,CAAC;AAC7C;AAEA,OAAO,SAASC,GAAGA,CAACP,QAAgB,EAAY;EAC9C,OAAOF,KAAK,CAACS,GAAG,CAACP,QAAQ,CAAC;AAC5B;AAEA,OAAO,SAASQ,OAAOA,CAACR,QAAgB,EAAES,IAAY,GAAG,CAAC,EAAa;EACrE,OAAOX,KAAK,CAACU,OAAO,CAACR,QAAQ,EAAES,IAAI,CAAC;AACtC;AAEA,OAAO,SAASC,cAAcA,CAACC,IAAY,EAAEJ,GAAW,GAAG,EAAE,EAAW;EACtE,OAAOT,KAAK,CAACY,cAAc,CAACC,IAAI,EAAEJ,GAAG,CAAC;AACxC;AAEA,OAAO,SAASK,IAAIA,CAACD,IAAY,EAAW;EAC1C,OAAOb,KAAK,CAACc,IAAI,CAACD,IAAI,CAAC;AACzB","ignoreList":[]}
@@ -1,5 +1,6 @@
1
1
  import { type TurboModule } from 'react-native';
2
2
  export interface Spec extends TurboModule {
3
+ isReady(): boolean;
3
4
  setDictPath(path: string): void;
4
5
  cut(sentence: string, hmm: boolean): string[];
5
6
  cutAll(sentence: string): string[];
@@ -1 +1 @@
1
- {"version":3,"file":"NativeJieba.d.ts","sourceRoot":"","sources":["../../../src/NativeJieba.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAErE,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,MAAM,EAAE,CAAC;IAC9C,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACnC,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,MAAM,EAAE,CAAC;IACvD,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzD,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5D,OAAO,CACL,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3C,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACnD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CAC7B;;AAED,wBAA+D"}
1
+ {"version":3,"file":"NativeJieba.d.ts","sourceRoot":"","sources":["../../../src/NativeJieba.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAErE,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,OAAO,IAAI,OAAO,CAAC;IACnB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,MAAM,EAAE,CAAC;IAC9C,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACnC,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,MAAM,EAAE,CAAC;IACvD,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzD,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5D,OAAO,CACL,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3C,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACnD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CAC7B;;AAED,wBAA+D"}
@@ -0,0 +1,16 @@
1
+ import type { Spec } from './NativeJieba';
2
+ export type JiebaWasmModule = {
3
+ cut(text: string, hmm?: boolean | null): string[];
4
+ cut_all(text: string): string[];
5
+ cut_for_search(text: string, hmm?: boolean | null): string[];
6
+ tag(sentence: string, hmm?: boolean | null): Array<{
7
+ word: string;
8
+ tag: string;
9
+ }>;
10
+ add_word(word: string, freq?: number | null, tag?: string | null): number;
11
+ };
12
+ export declare function setJiebaWasm(module: JiebaWasmModule): void;
13
+ export declare function isJiebaWasmReady(): boolean;
14
+ declare const Jieba: Spec;
15
+ export default Jieba;
16
+ //# sourceMappingURL=NativeJieba.web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NativeJieba.web.d.ts","sourceRoot":"","sources":["../../../src/NativeJieba.web.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAQ1C,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,MAAM,EAAE,CAAC;IAClD,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAChC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,MAAM,EAAE,CAAC;IAC7D,GAAG,CACD,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,OAAO,GAAG,IAAI,GACnB,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC;CAC3E,CAAC;AAIF,wBAAgB,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAE1D;AAED,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAaD,QAAA,MAAM,KAAK,EAAE,IA+CZ,CAAC;AAEF,eAAe,KAAK,CAAC"}
@@ -1,4 +1,5 @@
1
1
  export { cut, cutAll, cutForSearch, cutHMM, cutSmall, tag, extract, insertUserWord, find, } from './jieba';
2
2
  export type { Tagged, Keyword } from './jieba';
3
- export { initJieba } from './init';
3
+ export { prepareJieba, isJiebaReady } from './init';
4
+ export type { PrepareJiebaOptions } from './init';
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,GAAG,EACH,MAAM,EACN,YAAY,EACZ,MAAM,EACN,QAAQ,EACR,GAAG,EACH,OAAO,EACP,cAAc,EACd,IAAI,GACL,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,GAAG,EACH,MAAM,EACN,YAAY,EACZ,MAAM,EACN,QAAQ,EACR,GAAG,EACH,OAAO,EACP,cAAc,EACd,IAAI,GACL,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACpD,YAAY,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC"}
@@ -1,2 +1,33 @@
1
- export declare function initJieba(): Promise<void>;
1
+ export type PrepareJiebaOptions = {
2
+ /**
3
+ * Web only: URL (or fetch input) for the jieba-wasm `.wasm` binary. Most
4
+ * bundlers resolve it automatically, so this is only needed when the asset
5
+ * is served from a custom location. Ignored on iOS and Android.
6
+ */
7
+ wasmUrl?: string | URL | Request;
8
+ };
9
+ /**
10
+ * Optional on native (iOS/Android): the dictionary is located/extracted
11
+ * automatically on the first segmentation call, so you can call `cut`, `tag`,
12
+ * etc. directly without ever calling `prepareJieba`.
13
+ *
14
+ * Calling it is still useful as a *warm-up*: on Android's very first run the
15
+ * dictionary assets are extracted from the APK, and doing that work here
16
+ * (asynchronously, up front) avoids a one-time blocking pause on the first
17
+ * `cut`/`tag` call.
18
+ *
19
+ * On web it is **required** — it loads and instantiates the `jieba-wasm`
20
+ * binary, which cannot be done synchronously.
21
+ *
22
+ * Idempotent: repeated calls return the same promise.
23
+ */
24
+ export declare function prepareJieba(_options?: PrepareJiebaOptions): Promise<void>;
25
+ /**
26
+ * Whether jieba is ready to segment synchronously.
27
+ *
28
+ * Backed by the native engine state (not by whether `prepareJieba` was called),
29
+ * so it stays correct even when the dictionary is resolved lazily on the first
30
+ * `cut`/`tag` call. On iOS this is `true` from app launch.
31
+ */
32
+ export declare function isJiebaReady(): boolean;
2
33
  //# sourceMappingURL=init.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/init.ts"],"names":[],"mappings":"AAMA,wBAAgB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAkBzC"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/init.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC;CAClC,CAAC;AAIF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,GAAE,mBAAwB,GACjC,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAEtC"}
@@ -0,0 +1,18 @@
1
+ export type PrepareJiebaOptions = {
2
+ /**
3
+ * URL (or fetch input) for the jieba-wasm `.wasm` binary. Most bundlers
4
+ * resolve it automatically, so this is only needed when the asset is served
5
+ * from a custom location.
6
+ */
7
+ wasmUrl?: string | URL | Request;
8
+ };
9
+ /**
10
+ * **Required on web**: loads and instantiates the `jieba-wasm` binary (which
11
+ * cannot be done synchronously). Await it once before calling `cut`, `tag`, etc.
12
+ *
13
+ * Idempotent: repeated calls return the same promise.
14
+ */
15
+ export declare function prepareJieba(options?: PrepareJiebaOptions): Promise<void>;
16
+ /** Whether the wasm module has been loaded and jieba can segment. */
17
+ export declare function isJiebaReady(): boolean;
18
+ //# sourceMappingURL=init.web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.web.d.ts","sourceRoot":"","sources":["../../../src/init.web.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC;CAClC,CAAC;AAIF;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB7E;AAED,qEAAqE;AACrE,wBAAgB,YAAY,IAAI,OAAO,CAEtC"}
@@ -1 +1 @@
1
- {"version":3,"file":"jieba.d.ts","sourceRoot":"","sources":["../../../src/jieba.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AACnD,MAAM,MAAM,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvD,wBAAgB,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAE,OAAc,GAAG,MAAM,EAAE,CAEnE;AAED,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAEjD;AAED,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,GAAG,GAAE,OAAc,GAClB,MAAM,EAAE,CAEV;AAED,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAEjD;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAEvE;AAED,wBAAgB,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAE9C;AAED,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,MAAU,GAAG,OAAO,EAAE,CAErE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,MAAW,GAAG,OAAO,CAEtE;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE1C"}
1
+ {"version":3,"file":"jieba.d.ts","sourceRoot":"","sources":["../../../src/jieba.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AACnD,MAAM,MAAM,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvD,wBAAgB,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAE,OAAc,GAAG,MAAM,EAAE,CAEnE;AAED,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAEjD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAE,OAAc,GAAG,MAAM,EAAE,CAE5E;AAED,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAEjD;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAEvE;AAED,wBAAgB,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAE9C;AAED,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,MAAU,GAAG,OAAO,EAAE,CAErE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,MAAW,GAAG,OAAO,CAEtE;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE1C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-jieba",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Native Chinese text segmentation for React Native, powered by cppjieba.",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -15,6 +15,9 @@
15
15
  "files": [
16
16
  "src",
17
17
  "lib",
18
+ "README.md",
19
+ "CHANGELOG.md",
20
+ "LICENSE",
18
21
  "android/build.gradle",
19
22
  "android/CMakeLists.txt",
20
23
  "android/generated",
@@ -23,6 +26,8 @@
23
26
  "ios/generated",
24
27
  "cpp/JiebaImpl.h",
25
28
  "cpp/JiebaImpl.cpp",
29
+ "cpp/JiebaDictAndroid.h",
30
+ "cpp/JiebaDictAndroid.cpp",
26
31
  "cpp/cppjieba/LICENSE",
27
32
  "cpp/cppjieba/include/cppjieba",
28
33
  "cpp/cppjieba/deps/limonp/LICENSE",
@@ -94,6 +99,7 @@
94
99
  "eslint-plugin-ft-flow": "^3.0.11",
95
100
  "eslint-plugin-prettier": "^5.5.5",
96
101
  "jest": "^30.3.0",
102
+ "jieba-wasm": "^2.4.0",
97
103
  "lefthook": "^2.1.4",
98
104
  "prettier": "^3.8.1",
99
105
  "react": "19.2.3",
@@ -105,9 +111,15 @@
105
111
  "typescript": "^6.0.2"
106
112
  },
107
113
  "peerDependencies": {
114
+ "jieba-wasm": ">=2.0.0",
108
115
  "react": ">=18.0.0",
109
116
  "react-native": ">=0.85.0"
110
117
  },
118
+ "peerDependenciesMeta": {
119
+ "jieba-wasm": {
120
+ "optional": true
121
+ }
122
+ },
111
123
  "workspaces": [
112
124
  "example"
113
125
  ],
@@ -1,6 +1,7 @@
1
1
  import { TurboModuleRegistry, type TurboModule } from 'react-native';
2
2
 
3
3
  export interface Spec extends TurboModule {
4
+ isReady(): boolean;
4
5
  setDictPath(path: string): void;
5
6
  cut(sentence: string, hmm: boolean): string[];
6
7
  cutAll(sentence: string): string[];
@@ -0,0 +1,90 @@
1
+ import type { Spec } from './NativeJieba';
2
+
3
+ // `jieba-wasm` exposes the same segmentation primitives as cppjieba, but a
4
+ // smaller surface: cut / cutAll / cutForSearch / tag / add_word. The remaining
5
+ // native methods are polyfilled on top of those where the semantics allow, and
6
+ // throw otherwise. The wasm module is loaded lazily by `prepareJieba()` (see
7
+ // `init.web.ts`) and handed to this shim via `setJiebaWasm`.
8
+
9
+ export type JiebaWasmModule = {
10
+ cut(text: string, hmm?: boolean | null): string[];
11
+ cut_all(text: string): string[];
12
+ cut_for_search(text: string, hmm?: boolean | null): string[];
13
+ tag(
14
+ sentence: string,
15
+ hmm?: boolean | null
16
+ ): Array<{ word: string; tag: string }>;
17
+ add_word(word: string, freq?: number | null, tag?: string | null): number;
18
+ };
19
+
20
+ let wasm: JiebaWasmModule | null = null;
21
+
22
+ export function setJiebaWasm(module: JiebaWasmModule): void {
23
+ wasm = module;
24
+ }
25
+
26
+ export function isJiebaWasmReady(): boolean {
27
+ return wasm !== null;
28
+ }
29
+
30
+ function getWasm(): JiebaWasmModule {
31
+ if (!wasm) {
32
+ throw new Error(
33
+ 'react-native-jieba: jieba-wasm is not loaded yet. ' +
34
+ 'On web you must call (and await) prepareJieba() before any ' +
35
+ 'segmentation call.'
36
+ );
37
+ }
38
+ return wasm;
39
+ }
40
+
41
+ const Jieba: Spec = {
42
+ isReady() {
43
+ return isJiebaWasmReady();
44
+ },
45
+ setDictPath() {
46
+ // No-op on web: jieba-wasm bundles its own dictionary.
47
+ },
48
+ cut(sentence, hmm) {
49
+ return getWasm().cut(sentence, hmm);
50
+ },
51
+ cutAll(sentence) {
52
+ return getWasm().cut_all(sentence);
53
+ },
54
+ cutForSearch(sentence, hmm) {
55
+ return getWasm().cut_for_search(sentence, hmm);
56
+ },
57
+ cutHMM(sentence) {
58
+ // jieba-wasm has no HMM-only mode; precise cut with HMM enabled is the
59
+ // closest equivalent.
60
+ return getWasm().cut(sentence, true);
61
+ },
62
+ cutSmall(sentence, _maxWordLen) {
63
+ // jieba-wasm does not expose a max-word-length cut; fall back to precise
64
+ // cut. The maxWordLen argument is accepted for API parity but ignored.
65
+ return getWasm().cut(sentence, true);
66
+ },
67
+ tag(sentence) {
68
+ return getWasm().tag(sentence);
69
+ },
70
+ extract() {
71
+ throw new Error(
72
+ 'react-native-jieba: extract() (TF-IDF keyword extraction) is not ' +
73
+ 'supported on web — jieba-wasm does not ship the IDF dictionary.'
74
+ );
75
+ },
76
+ insertUserWord(word, tag) {
77
+ // add_word returns the inserted word's frequency (>= 0 on success).
78
+ return (
79
+ getWasm().add_word(word, undefined, tag === '' ? undefined : tag) >= 0
80
+ );
81
+ },
82
+ find(word) {
83
+ // jieba-wasm has no dictionary lookup; approximate it by checking whether
84
+ // the word survives precise (non-HMM) segmentation as a single token.
85
+ const segments = getWasm().cut(word, false);
86
+ return segments.length === 1 && segments[0] === word;
87
+ },
88
+ };
89
+
90
+ export default Jieba;
package/src/index.tsx CHANGED
@@ -10,4 +10,5 @@ export {
10
10
  find,
11
11
  } from './jieba';
12
12
  export type { Tagged, Keyword } from './jieba';
13
- export { initJieba } from './init';
13
+ export { prepareJieba, isJiebaReady } from './init';
14
+ export type { PrepareJiebaOptions } from './init';
package/src/init.ts CHANGED
@@ -2,11 +2,37 @@ import { Platform } from 'react-native';
2
2
  import Jieba from './NativeJieba';
3
3
  import JiebaAndroidHelper from './NativeJiebaAndroidHelper';
4
4
 
5
- let initPromise: Promise<void> | null = null;
5
+ export type PrepareJiebaOptions = {
6
+ /**
7
+ * Web only: URL (or fetch input) for the jieba-wasm `.wasm` binary. Most
8
+ * bundlers resolve it automatically, so this is only needed when the asset
9
+ * is served from a custom location. Ignored on iOS and Android.
10
+ */
11
+ wasmUrl?: string | URL | Request;
12
+ };
6
13
 
7
- export function initJieba(): Promise<void> {
8
- if (initPromise) return initPromise;
9
- initPromise = (async () => {
14
+ let preparePromise: Promise<void> | null = null;
15
+
16
+ /**
17
+ * Optional on native (iOS/Android): the dictionary is located/extracted
18
+ * automatically on the first segmentation call, so you can call `cut`, `tag`,
19
+ * etc. directly without ever calling `prepareJieba`.
20
+ *
21
+ * Calling it is still useful as a *warm-up*: on Android's very first run the
22
+ * dictionary assets are extracted from the APK, and doing that work here
23
+ * (asynchronously, up front) avoids a one-time blocking pause on the first
24
+ * `cut`/`tag` call.
25
+ *
26
+ * On web it is **required** — it loads and instantiates the `jieba-wasm`
27
+ * binary, which cannot be done synchronously.
28
+ *
29
+ * Idempotent: repeated calls return the same promise.
30
+ */
31
+ export function prepareJieba(
32
+ _options: PrepareJiebaOptions = {}
33
+ ): Promise<void> {
34
+ if (preparePromise) return preparePromise;
35
+ preparePromise = (async () => {
10
36
  if (Platform.OS === 'android') {
11
37
  if (!JiebaAndroidHelper) {
12
38
  throw new Error(
@@ -18,8 +44,19 @@ export function initJieba(): Promise<void> {
18
44
  }
19
45
  // iOS: OnLoad.mm already configured the dict path from the bundle.
20
46
  })().catch((err) => {
21
- initPromise = null;
47
+ preparePromise = null;
22
48
  throw err;
23
49
  });
24
- return initPromise;
50
+ return preparePromise;
51
+ }
52
+
53
+ /**
54
+ * Whether jieba is ready to segment synchronously.
55
+ *
56
+ * Backed by the native engine state (not by whether `prepareJieba` was called),
57
+ * so it stays correct even when the dictionary is resolved lazily on the first
58
+ * `cut`/`tag` call. On iOS this is `true` from app launch.
59
+ */
60
+ export function isJiebaReady(): boolean {
61
+ return Jieba.isReady();
25
62
  }
@@ -0,0 +1,53 @@
1
+ import {
2
+ setJiebaWasm,
3
+ isJiebaWasmReady,
4
+ type JiebaWasmModule,
5
+ } from './NativeJieba.web';
6
+
7
+ export type PrepareJiebaOptions = {
8
+ /**
9
+ * URL (or fetch input) for the jieba-wasm `.wasm` binary. Most bundlers
10
+ * resolve it automatically, so this is only needed when the asset is served
11
+ * from a custom location.
12
+ */
13
+ wasmUrl?: string | URL | Request;
14
+ };
15
+
16
+ let preparePromise: Promise<void> | null = null;
17
+
18
+ /**
19
+ * **Required on web**: loads and instantiates the `jieba-wasm` binary (which
20
+ * cannot be done synchronously). Await it once before calling `cut`, `tag`, etc.
21
+ *
22
+ * Idempotent: repeated calls return the same promise.
23
+ */
24
+ export function prepareJieba(options: PrepareJiebaOptions = {}): Promise<void> {
25
+ if (preparePromise) return preparePromise;
26
+ preparePromise = (async () => {
27
+ // `jieba-wasm` resolves to its `web` build under the `browser`/`import`
28
+ // conditions, whose default export is an async initializer that fetches
29
+ // and instantiates the wasm binary.
30
+ const wasm = (await import('jieba-wasm')) as unknown as {
31
+ default: (input?: string | URL | Request) => Promise<unknown>;
32
+ } & JiebaWasmModule;
33
+
34
+ // With no argument, jieba-wasm's `web` initializer resolves the binary via
35
+ // `new URL('jieba_rs_wasm_bg.wasm', import.meta.url)` *relative to its own
36
+ // module*, which bundlers (Vite, Webpack 5, …) rewrite to the correct
37
+ // emitted asset URL in both dev and production. Only pass `wasmUrl` when the
38
+ // consumer explicitly overrides where the binary is served from — passing a
39
+ // wrong/relative path here makes the dev server return index.html and wasm
40
+ // instantiation fails with a bad magic word.
41
+ await wasm.default(options.wasmUrl);
42
+ setJiebaWasm(wasm);
43
+ })().catch((err) => {
44
+ preparePromise = null;
45
+ throw err;
46
+ });
47
+ return preparePromise;
48
+ }
49
+
50
+ /** Whether the wasm module has been loaded and jieba can segment. */
51
+ export function isJiebaReady(): boolean {
52
+ return isJiebaWasmReady();
53
+ }
package/src/jieba.ts CHANGED
@@ -11,10 +11,7 @@ export function cutAll(sentence: string): string[] {
11
11
  return Jieba.cutAll(sentence);
12
12
  }
13
13
 
14
- export function cutForSearch(
15
- sentence: string,
16
- hmm: boolean = true
17
- ): string[] {
14
+ export function cutForSearch(sentence: string, hmm: boolean = true): string[] {
18
15
  return Jieba.cutForSearch(sentence, hmm);
19
16
  }
20
17