ŴÀŠḾ Éñĝîñé ÀƂÎ
Ţĥé ƃŕöŵšéŕ ƃüîļđ öƒ ķàþî (kapi/cmd/kapi-wasm-cli) ŕéĝîšţéŕš à šéţ öƒ ĝļöƃàļ
ĴŠ ƒüñçţîöñš àţ ƃööţ. Ţĥàţ šéţ îš à ṽéŕšîöñéđ çöñţŕàçţ, ţĥé ÀƂÎ çöñšüḿéđ ƃý
ţĥé @neokapi/engine ñþḿ þàçķàĝé (packages/engine), ŵĥîçĥ ŵŕàþš îţ îñ ţĥé
ţýþéđ KapiRuntime ƒàçàđé.
Çöñţŕàçţ
- Šîñĝļé ŕéĝîšţŕàţîöñ þöîñţ. Éṽéŕý éñţŕý þöîñţ îš đéçļàŕéđ îñ ţĥé
engineExportsţàƃļé îñkapi/cmd/kapi-wasm-cli/main.goàñđ îñšţàļļéđ öñglobalThisƒŕöḿ ţĥéŕé. Ñöţĥîñĝ éļšé ŕéĝîšţéŕš éñĝîñé ĝļöƃàļš. - Ƒéàţüŕé đéţéçţîöñ.
kapiEngineABI()ŕéţüŕñš{abi, version, functions}: ţĥé ÀƂÎ ḿàĵöŕ ṽéŕšîöñ, ţĥé ķàþî ƃüîļđ ṽéŕšîöñ, àñđ ţĥé ļîšţ öƒ ŕéĝîšţéŕéđ ĝļöƃàļ ñàḿéš. À ƃüîļđ ŵîţĥöüţkapiEngineABIþŕéđàţéš ţĥé đéšçŕîþţöŕ àñđ îš ţŕéàţéđ àš àƃî 0 (þŕöƃé îñđîṽîđüàļ ĝļöƃàļš). - Àđđîţîṽé ŵîţĥîñ à ṽéŕšîöñ. Ƒöŕ öñé
abiṽàļüé, çĥàñĝéš àŕé šţŕîçţļý àđđîţîṽé: ñéŵ ƒüñçţîöñš ḿàý àþþéàŕ îñfunctions, ƃüţ éẋîšţîñĝ ñàḿéš, šîĝñàţüŕéš, àñđ þàýļöàđ šĥàþéš ñéṽéŕ çĥàñĝé öŕ đîšàþþéàŕ. Ŕéñàḿîñĝ öŕ ŕéḿöṽîñĝ àñ éñţŕý þöîñţ, öŕ çĥàñĝîñĝ à šîĝñàţüŕé îñçöḿþàţîƃļý, ƃüḿþš ţĥé ṽéŕšîöñ. - Ƃööţ ĥàñđšĥàķé. Ţĥé ĥöšţ îñšţàļļš îţš
fs/processšĥîḿš (ţĥéwasm_exec.jséñṽîŕöñḿéñţ) àñđ ţĥé ŠǪĻîţé ƃŕîđĝé (__kapiSQL, šéé Šţöŕàĝé) ƃéƒöŕé îñšţàñţîàţîöñ; àƒţéŕ ŕéĝîšţéŕîñĝ ţĥé ĝļöƃàļš, ţĥé éñĝîñé îñṽöķéš ţĥé ĥöšţ'š__kapiCliReady()çàļļƃàçķ àñđ ţĥéñ ƃļöçķš ƒöŕéṽéŕ šö ţĥé ĝļöƃàļš šţàý çàļļàƃļé. Îñ à ƃŕöŵšéŕ ţĥé ĥöšţ îš ţĥé éñĝîñé'š Ŵöŕķéŕ (Ţĥé Ŵöŕķéŕ), šö ţĥé ĝļöƃàļš ļîṽé ţĥéŕé àñđ ţĥé ƒàçàđé ŕéàçĥéš ţĥéḿ ƃý ḿéššàĝé. - Ŕéṽéŕšé ƃŕîđĝéš. Šöḿé ƒéàţüŕéš çàļļ ƃàçķ îñţö öþţîöñàļ ĥöšţ-þŕöṽîđéđ
ĝļöƃàļš:
__kapiPdfium(ÞĐƑ ţéẋţ + ĝéöḿéţŕý),kapiLocalGenerate(öñ-đéṽîçé ĻĻḾ),kapiLocalNER(öñ-đéṽîçé ÑÉŔ), àñđkapiBrowserTranslate(ŵîţĥ ţĥé þļàţƒöŕḿTranslatorÀÞÎ). Éàçĥ đéĝŕàđéš ŵîţĥ àñ àçţîöñàƃļé éŕŕöŕ ŵĥéñ îţš ƃŕîđĝé îš àƃšéñţ. Ţĥé ţýþéđ îñţéŕƒàçéš ļîṽé îñpackages/engine/src/capabilities.ts. À þàĝé îñšţàļļš ţĥéḿ öñ îţš öŵñglobalThis, àñđ ţĥé éñĝîñé ƒîñđš ţĥéḿ ţĥéŕé ƒŕöḿ ţĥé þàĝé öŕ ƒŕöḿ à Ŵöŕķéŕ.
Ţĥé Ŵöŕķéŕ
bootKapiRuntime šţàŕţš ţĥé éñĝîñé îñ à đéđîçàţéđ Ŵöŕķéŕ
(packages/engine/src/worker.ts) ŵĥéŕéṽéŕ Worker éẋîšţš: Ĝö, ŠǪĻîţé àñđ ţĥé
éñĝîñé'š ƒîļé šýšţéḿ ŕüñ ţĥéŕé, öƒƒ ţĥé þàĝé'š ţĥŕéàđ. { worker: false }, öŕ
àñ éñṽîŕöñḿéñţ ŵîţĥöüţ Worker (Ñöđé, à ţéšţ), ŕüñš îţ öñ ţĥé çàļļîñĝ ţĥŕéàđ
àš ƃéƒöŕé, ŵîţĥ ţĥé ŵöŕķšþàçé îñ ḿéḿöŕý.
- Çàļļš ƃý ḿéššàĝé. Ţĥé ƒàçàđé šéñđš éàçĥ çàļļ àš à ḿéššàĝé ñàḿîñĝ ţĥé
éñĝîñé ĝļöƃàļ àñđ îţš àŕĝüḿéñţš (
packages/engine/src/protocol.ts), àñđ ţĥé Ŵöŕķéŕ àñšŵéŕš ŵîţĥ ţĥé ṽàļüé. Çàļļš ţĥàţ àŕé ñöţ éñĝîñé ĝļöƃàļš (removeDatabase,reset,syncContext, àñđ ŕéàđîñĝ ƃàçķ à ţŕàçé) ŕüñ ƃéšîđé ţĥéḿ îñ ţĥé Ŵöŕķéŕ (packages/engine/src/local.ts).kbf,segment,segmentEnginesàñđremoveDatabaseàñšŵéŕ Þŕöḿîšéš öñ ţĥé ƒàçàđé, îñ ƃöţĥ ḿöđéš. - Ţĥé ƒîļé šýšţéḿ ĥàš à ḿîŕŕöŕ öñ ţĥé þàĝé.
runtime.volšţàýš šýñçĥŕöñöüš: ţĥé þàĝé ĥöļđš à çöþý öƒ ţĥé éñĝîñé'š ƒîļé šýšţéḿ, à ŵŕîţé öñ ţĥé þàĝé ŕéàçĥéš ţĥé Ŵöŕķéŕ ƃéƒöŕé ţĥé ñéẋţ çàļļ (ḿéššàĝéš ķééþ ţĥéîŕ öŕđéŕ), àñđ ţĥé Ŵöŕķéŕ šéñđš ţĥé çĥàñĝéš à çàļļ ḿàđé ƃéƒöŕé ţĥé çàļļ'š àñšŵéŕ, šö à þàĝé ţĥàţ ŕéàđšvolàƒţéŕ à çàļļ šééš ţĥéḿ.memfsŕéþöŕţš éàçĥ çĥàñĝéđ þàţĥ (onChange) ƒöŕ ţĥîš. - Ţĥé ÀƂÎ đéšçŕîþţöŕ. Ţĥé Ŵöŕķéŕ šéñđš
kapiEngineABI()ŵîţĥ îţš ŕéàđý ḿéššàĝé, àñđ ţĥé ƒàçàđé îñšţàļļš îţ öñ ţĥé þàĝé, šöengineABI()àñđhasEngineFunction()àñšŵéŕ ţĥéŕé. - Ŕéṽéŕšé ƃŕîđĝéš šţàý öñ ţĥé þàĝé. Ŵîţĥ éàçĥ çàļļ ţĥé ƒàçàđé šéñđš ŵĥîçĥ
ƃŕîđĝéš ţĥé þàĝé ĥàš, àñđ ţĥé Ŵöŕķéŕ îñšţàļļš à šţàñđ-îñ ƒöŕ éàçĥ ţĥàţ àšķš
ţĥé þàĝé àñđ ŵàîţš ƒöŕ îţš àñšŵéŕ. À šţàñđ-îñ àñšŵéŕš ŵîţĥ à Þŕöḿîšé, šö ţĥé
éñĝîñé ŵàîţš ƒöŕ îţ öñ à ĝöŕöüţîñé:
labSegmentAsyncîšlabSegmentàñšŵéŕéđ àš à Þŕöḿîšé ƒöŕ ţĥàţ ŕéàšöñ, àñđ ţĥé ÎÇÜ4Ẋ éñĝîñé (core/segment/icu4xjs) àççéþţš à Þŕöḿîšé ƒŕöḿ îţš ƃŕîđĝé. Ţĥé Ŵöŕķéŕ àñšŵéŕškapiIntlSentenceBreaksîţšéļƒ, šîñçéIntl.Segmenteréẋîšţš ţĥéŕé, àñđ ḿîŕŕöŕš ţĥé þŕéšéñçé öƒ ţĥé þļàţƒöŕḿTranslatorÀÞÎ. - Ļöàđîñĝ
wasm_exec.js. Ţĥé Ŵöŕķéŕ îḿþöŕţš îţ àš à ḿöđüļé, ƒàļļîñĝ ƃàçķ ţöimportScriptsîñ à çļàššîç Ŵöŕķéŕ. À ĥöšţ öñ àñöţĥéŕ öŕîĝîñ šéŕṽéš îţ ŵîţĥ ÇÖŔŠ, àš îţ àļŕéàđý đöéš ƒöŕ ţĥé éñĝîñé ƃîñàŕý.
Šţöŕàĝé
Éṽéŕý šţöŕé îñ ţĥé ƃŕöŵšéŕ ƃüîļđ îš ţĥé ñàţîṽé çöđé: ţĥé ŵöŕķšþàçé àñđ îţš
öþéŕàţîöñ ļöĝ, ţĥé þŕöĵéçţöŕ, ţĥé çöñţéñţ ḿéḿöŕý, ţĥé ţéŕḿš šţöŕé, ţĥé ṽöîçé
šţöŕé, ţĥé đéçîšîöñ ļéđĝéŕ, ţĥé çöñţéẋţ ĝŕàþĥ àñđ ţĥé ƃļöçķ çàçĥé. Ţĥéý àŕé ŠǪĻ
ƃéĥîñđ core/storage, àñđ ţĥé ƃŕöŵšéŕ ƃüîļđ'š đŕîṽéŕ ŕüñš ţĥàţ ŠǪĻ öñ ţĥé
öƒƒîçîàļ ŠǪĻîţé ŴéƃÀššéḿƃļý ƃüîļđ, @sqlite.org/sqlite-wasm.
-
Ŵĥéŕé ţĥé ŵöŕķšþàçé îš ķéþţ. Îñ ţĥé Ŵöŕķéŕ, ţĥé éñĝîñé ķééþš îţš đàţàƃàšéš îñ ŠǪĻîţé'š
opfs-sahpoolṼƑŠ, îñ ţĥé öŕîĝîñ þŕîṽàţé ƒîļé šýšţéḿ, àñđ ţĥé ƒîļéš öƒ îţš ƒîļé šýšţéḿ îñ à đàţàƃàšé öƒ îţš öŵñ îñ ţĥé šàḿé þööļ (/.kapi-engine/volume.db, öüţšîđé ţĥé đŕîṽéŕ'š ñàḿéšþàçé), ŵŕîţţéñ àƒţéŕ éàçĥ çàļļ. Ƃöţĥ šüŕṽîṽé à ŕéļöàđ àñđ à ƃŕöŵšéŕ ŕéšţàŕţ, àñđ ñééđ ñö ÇÖÖÞ öŕ ÇÖÉÞ ĥéàđéŕš, ŵĥîçĥ ĜîţĤüƃ Þàĝéš çàññöţ šéţ.runtime.storagešàýš ŵĥîçĥ àþþļîéš:{ kind: "opfs" }, öŕ{ kind: "memory", reason }ŵîţĥreasonöñé öƒdisabled,main-thread,unsupported,another-tab,takenöŕfailed, àñđdescribeStorage()ţüŕñš îţ îñţö à šéñţéñçé ƒöŕ à þàĝé.runtime.onStorageChange()ŕéþöŕţš éàçĥ çĥàñĝé. Ţĥé þööļ îš ñàḿéđ ƃý à ķéý (BootOptions.persist, đéƒàüļţ"kapi"); ţĥé đöçš ķéý îţ ƃý ţĥéîŕ ƃàšé ÜŔĻ, šîñçé ţĥé šţàƃļé đöçš, ţĥé þŕéṽîéŵ çĥàññéļ àñđ éàçĥ þüļļ ŕéǫüéšţ þŕéṽîéŵ šĥàŕé àñ öŕîĝîñ àñđ šéŕṽé đéŕéñţ éñĝîñéš. -
Öñé ţàƃ öŵñš ţĥé þööļ. Ţĥé þööļ ĥöļđš à šýñçĥŕöñöüš ĥàñđļé öñ éṽéŕý ƒîļé, ŵĥîçĥ öñļý öñé çöñţéẋţ ḿàý ĥöļđ, šö ţĥé Ŵöŕķéŕ ƒîŕšţ ţàķéš à Ŵéƃ Ļöçķ ñàḿéđ ƒöŕ ţĥé þööļ àñđ ĥöļđš îţ ƒöŕ îţš ļîƒé. Éṽéŕý ţàƃ ŵàîţš à ḿöḿéñţ ƒöŕ ţĥé ļöçķ (à ŕéļöàđ ŕéļéàšéš îţ àš ţĥé öļđ þàĝé çļöšéš).
BootOptions.whenHeldšàýš ŵĥàţ à ţàƃ đöéš ŵĥéñ àñöţĥéŕ ţàƃ šţîļļ ĥöļđš îţ:"memory"(ţĥé đéƒàüļţ) ŕüñš îñ ḿéḿöŕý ŵîţĥreason: "another-tab","wait"ŵàîţš üñţîļ ţĥé öŵñéŕ ļéţš ĝö, àñđ"take"ţàķéš ţĥé ŵöŕķšþàçé öṽéŕ. Ƃéƒöŕé îñšţàļļîñĝ ţĥé þööļ ţĥé Ŵöŕķéŕ çĥéçķš ţĥàţ ñö öţĥéŕ çöñţéẋţ šţîļļ ĥöļđš îţš ƒîļéš àñđ ŵàîţš ƒöŕ öñé ţĥàţ îš çļöšîñĝ: à ƒàîļéđ îñšţàļļ îñ ţĥîš ŕéļéàšé öƒsqlite-wasmŕéḿöṽéš ţĥé þööļ'š đîŕéçţöŕý. Ţĥé þööļ ĝŕöŵš ƃéţŵééñ çàļļš, šîñçé ĝŕöŵîñĝ îţ ŵàîţš öñ ţĥé ƒîļé šýšţéḿ, ķééþîñĝ šþàŕé šļöţš ƒöŕ ţĥé đàţàƃàšéš àñđ ĵöüŕñàļš à çàļļ çŕéàţéš. -
Ĥàñđîñĝ ţĥé ŵöŕķšþàçé öṽéŕ.
runtime.takeOver()ḿöṽéš ţĥé ŵöŕķšþàçé ţö ţĥé ţàƃ ţĥàţ çàļļš îţ. Ţĥé çàļļš îñ ƒļîĝĥţ ƒîñîšĥ ƒîŕšţ; ţĥéñ ţĥé ƒàçàđé šţàŕţš à šéçöñđ Ŵöŕķéŕ ţĥàţ ŕéǫüéšţš ţĥé ļöçķ ŵîţĥsteal: true. Šţéàļîñĝ ŕéĵéçţš ţĥé öŵñéŕ'š ĥéļđ ļöçķ ŕéǫüéšţ, ŵĥîçĥ îš ĥöŵ ţĥé öŵñéŕ ļéàŕñš îţ ļöšţ ţĥé ŵöŕķšþàçé: îţš Ŵöŕķéŕ ķééþš ţĥé ƒîļé çĥàñĝéš ñöţ ýéţ ķéþţ, šţöþš üšîñĝ ţĥé þööļ àñđ šéñđšlost, àñđ îţš þàĝé ƒàîļš ţĥé çàļļš îñ ƒļîĝĥţ, šţöþš ţĥàţ Ŵöŕķéŕ (ŵĥîçĥ ŕéļéàšéš ţĥé þööļ'š ƒîļé ĥàñđļéš) àñđ šţàŕţš àñöţĥéŕ îñ ḿéḿöŕý ŵîţĥ ţĥé þàĝé'š ƒîļéš, šöstorageƃéçöḿéš{ kind: "memory", reason: "taken" }. Ţĥé ñéŵ öŵñéŕ ŵàîţš ƒöŕ ţĥé ĥàñđļéš ţö ƃé ƒŕéé (üþ ţö 15 šéçöñđš), îñšţàļļš ţĥé þööļ àñđ ŕéþļàçéš ţĥé ţàƃ'š ƒîļéš ŵîţĥ ţĥé ķéþţ öñéš; ţĥé ƒàçàđé ḿöṽéš öñţö ţĥàţ Ŵöŕķéŕ àñđ šţöþš ţĥé öļđ öñé. Ŵĥéñ ţĥé þööļ çàññöţ ƃé öþéñéđ,takeOver()ŕéĵéçţš àñđ ţĥé ţàƃ šţàýš àš îţ ŵàš. À Ŵöŕķéŕ ţĥàţ ļöšéš ţĥé ļöçķ ƃéƒöŕé îţ îš ŕéàđý îš ŕéþļàçéđ ƃý öñé îñ ḿéḿöŕý. Ţĥé þļàýĝŕöüñđ'š ƒîļéš þàñéļ öƒƒéŕš Üšé ţĥé ŵöŕķšþàçé ĥéŕé ŵĥîļé àñöţĥéŕ ţàƃ ĥöļđš ţĥé ŵöŕķšþàçé. -
Ļöçķš ƃéţŵééñ çöññéçţîöñš. Ţĥé þööļ'š öŵñ ļöçķš öñļý ŕéḿéḿƃéŕ ţĥé ļéṽéļ àšķéđ ƒöŕ. Ţĥé éñĝîñé öþéñš šéṽéŕàļ çöññéçţîöñš ţö öñé đàţàƃàšé, šö ţĥé ƃŕîđĝé îñšţàļļš à ļöçķ ţàƃļé öṽéŕ ţĥé þööļ'š ḿéţĥöđš (
packages/engine/src/locks.ts) ţĥàţ ķééþš ŠǪĻîţé'š ļöçķ ļéṽéļš þéŕ đàţàƃàšé, àšmemdbàñđos_unix.cđö ŵîţĥîñ öñé þŕöçéšš: à ŵŕîţé ƃéšîđé àñöţĥéŕ çöññéçţîöñ'š ţŕàñšàçţîöñ ŕéþöŕţšdatabase is lockedàţ öñçé, àš îţ đöéš îñ ḿéḿöŕý. -
Ţĥé ŵöŕķšþàçé îš à çàçĥé. Ţĥé ƃŕöŵšéŕ ḿàý éṽîçţ ŵĥàţ à šîţé ķééþš (Šàƒàŕî ŕéḿöṽéš đàţà à šçŕîþţ ŵŕöţé àƒţéŕ šéṽéñ đàýš ŵîţĥöüţ îñţéŕàçţîöñ), šö ţĥé ŵöŕķšþàçé îñ à ƃŕöŵšéŕ îš à çàçĥé öƒ à ļöĝ ţĥàţ šĥöüļđ àļšö ļîṽé éļšéŵĥéŕé.
kapiExportWorkspace()þàçķš ţĥé éñĝîñé'š ƒîļéš àñđ ţĥé çöñţéẋţ öƒ éṽéŕý þŕöĵéçţ àḿöñĝ ţĥéḿ îñţö à ŵöŕķšþàçé þàçķàĝé (kpz.KindWorkspace,kapi-workspace): ţĥé ƒîļéš üñđéŕfiles/, àñđ þéŕ þŕöĵéçţ à çöñţéẋţ þàçķàĝé üñđéŕcontexts/, ţĥé öþéŕàţîöñ ļöĝkapi store exportŵŕîţéš.kapiImportWorkspace(bytes)ŵŕîţéš ţĥé ƒîļéš àñđ ḿéŕĝéš éàçĥ ļöĝ, àškapi store importđöéš, ŵĥîçĥ ŕéƃüîļđš ţĥé þŕöĵéçţ'š šţöŕéš. À ţéŕḿš šţöŕé öüţšîđé éṽéŕý þŕöĵéçţ (öñékapi terms import --fileŵŕöţé, šàý) ĥàš ñö ļöĝ, šö îţ ţŕàṽéļš àš à ţéŕḿš ƃüñđļé üñđéŕtermstores/, ŵĥîçĥ ţĥé ḿàñîƒéšţ ḿàþš ţö ţĥé šţöŕé'š þàţĥ, àñđ àñ îḿþöŕţ àđđš îţš çöñçéþţš àñđ ŕéļàţîöñš ţö à šţöŕé àţ ţĥàţ þàţĥ. Ţĥé šţöŕéš îñ à þŕöĵéçţ'š.kapi/àŕé þŕöĵéçţîöñš öƒ îţš ļöĝ àñđ šţàý öüţ; šö đö ţĥé đàţà ŕööţ,/tmpàñđ ţĥé ļàƃ'š öŵñ đîŕéçţöŕý (/.lab). Ţĥé ƒàçàđé'šexportWorkspace()àñđimportWorkspace()ŵŕàþ ţĥéḿ, àñđ ţĥé þļàýĝŕöüñđ'š ƒîļéš þàñéļ öƒƒéŕš ƃöţĥ. -
À ŕéšéţ, ţĥéñ àñ îḿþöŕţ. À ŕéšéţ ƒöŕĝéţš éàçĥ þŕöĵéçţ îñ ţĥé ŵöŕķšþàçé (
workspace.Forget), ŵĥîçĥ ŕéçöŕđšproject.forgetîñ ţĥé ļöĝ àñđ ķééþš ţĥé öþéŕàţîöñš ƃéƒöŕé îţ ƒöŕ ĥîšţöŕý; à šţöŕé šţàŕţš àƒţéŕ ţĥé ļàţéšţ ŕéḿöṽàļ. Ţĥé ŵöŕķšþàçé ţŕéàţš àñ öþéŕàţîöñ ĥéļđ öñļý ƃéƒöŕé îţš þŕöĵéçţ'š ŕéḿöṽàļ àš ñöţ ĥéļđ:Recordŵŕîţéš îţ àĝàîñ àƒţéŕ ţĥé ŕéḿöṽàļ, à þüļļ çöüñţš îţ àš ñéŵ, à þüšĥ ļéàṽéš öüţ éṽéŕý öþéŕàţîöñ ƃéƒöŕé ţĥé ŕéḿöṽàļ, àñđ ţĥé ŕéḿöṽàļ çļéàŕš ŵĥàţ ţĥé ŵöŕķšþàçé ķñéŵ àƃöüţ ţĥé þŕöĵéçţ'š ŕéḿöţéš. Šö îḿþöŕţîñĝ ţĥé þàçķàĝé éẋþöŕţéđ ƃéƒöŕé à ŕéšéţ, îñ ţĥé šàḿé ƃŕöŵšéŕ, ḿéŕĝéš ţĥé þŕöĵéçţ'š ļöĝ àĝàîñ àñđ ŕéƃüîļđš îţš šţöŕéš. -
Šýñç ţĥŕöüĝĥ à ƒöļđéŕ.
kapiSyncContext(remote, options)þüļļš à þŕöĵéçţ'š çöñţéẋţ ƒŕöḿ à ŕéḿöţé ţĥé þàĝé ĥöļđš àñđ þüšĥéš ŵĥàţ ţĥé éñĝîñé ŕéçöŕđéđ (App.SyncProjectContextWith, ţĥé šàḿé þüļļ àñđ þüšĥkapi context syncŕüñš), àñđ ŕéšöļṽéš ţö{pull, push}. Ţĥé ŕéḿöţé îš àñ öƃĵéçţ ŵîţĥlist,getàñđput(kapi/cmd/kapi-wasm-cli/contextremote.go);folderRemote(handle)(packages/engine/src/folderremote.ts) ƃüîļđš öñé öṽéŕ àFileSystemDirectoryHandle, ƒŕöḿshowDirectoryPicker()öŕ ţĥé öŕîĝîñ þŕîṽàţé ƒîļé šýšţéḿ. Ţĥé ƒöļđéŕ ķééþš ţĥé ļàýöüţFileRemoteķééþš öñ đîšķ, öñé ƒîļé þéŕ öƃĵéçţ, éàçĥ ŵŕîţţéñ üñđéŕ à đöţ-ñàḿé àñđ ḿöṽéđ îñţö þļàçé, šö à ŕéçîþé ŵîţĥcontext: {backend: file, path: <folder>}öñ ţĥé šàḿé çöḿþüţéŕ šĥàŕéš ţĥé çöñţéẋţ. Ţĥé ƒàçàđé'šsyncContext(folder, opts)šéñđš ţĥé ĥàñđļé ţö ţĥé Ŵöŕķéŕ, ŵĥéŕé ţĥé ŕéḿöţé îš ƃüîļţ, àñđ ţĥé ƒîļéš þàñéļ öƒƒéŕš Šýñç çöñţéẋţ ŵîţĥ à ƒöļđéŕ ŵĥéŕéshowDirectoryPickeréẋîšţš (Çĥŕöḿîüḿ). Ţĥé öţĥéŕ ƃàçķéñđš šţàý ñàţîṽé: àgitƃàçķéñđ ŕüñš ţĥégitéẋéçüţàƃļé, ŵĥîçĥ à þàĝé çàññöţ šţàŕţ, àñđ ţĥés3ƃàçķéñđ ŕéàđš ţĥé ÀŴŠ çŕéđéñţîàļ çĥàîñ, ŵĥîçĥ à þàĝé ĥàš ñö šàƒé þļàçé ţö ĥöļđ. -
Ţĥé ƃŕîđĝé.
packages/engine/src/sqlite.tsļöàđš ţĥé ḿöđüļé àñđ îñšţàļļš öñé öƃĵéçţ öñglobalThis,__kapiSQL, ƃéƒöŕé Ĝö šţàŕţš. Ţĥé Ĝö đŕîṽéŕ (core/storage/driver_js.go,core/storage/sqlitejs_js.go) ŕéĝîšţéŕš ŵîţĥdatabase/sqlàñđ çàļļš ţĥé ƃŕîđĝé šýñçĥŕöñöüšļý ţĥŕöüĝĥsyscall/js, šö Ĝö àñđ ŠǪĻîţé šĥàŕé ţĥé þàĝé'š ḿàîñ ţĥŕéàđ. Àŕĝüḿéñţš àñđ ŕéšüļţ ŕöŵš çŕöšš îñ öñé þàçķéđ ƃýţé ƃüƒƒéŕ þéŕ çàļļ. À ƒàîļüŕé çöḿéš ƃàçķ àš ŠǪĻîţé'š öŵñ ḿéššàĝé àñđ éẋţéñđéđ ŕéšüļţ çöđé. -
Ŵĥéŕé ţĥé đàţàƃàšéš ļîṽé. Ñàḿéđ ƃý àƃšöļüţé þàţĥ, îñ ţĥé þööļ öŕ, îñ ḿéḿöŕý, îñ ŠǪĻîţé'š
memdbṼƑŠ. Éṽéŕý çöññéçţîöñ ţö öñé ñàḿé šĥàŕéš ţĥé đàţàƃàšé, àñđATTACHƃý þàţĥ ŕéàçĥéš îţ, šîñçé ţĥé ƃŕîđĝé ḿàķéš îţš ṼƑŠ ţĥé đéƒàüļţ. Îñ ḿéḿöŕý ţĥé ƃŕîđĝé ĥöļđš à çöññéçţîöñ öƒ îţš öŵñ öñ éàçĥ ñàḿé, šö à đàţàƃàšé öüţļîṽéš ţĥé þööļš ţĥàţ öþéñ àñđ çļöšé îţ ƃéţŵééñ çöḿḿàñđš. Ţĥé éñĝîñé ñàḿéš îţš đàţà ŕööţ/.kapi-data(KAPI_DATA_DIR), ŵĥéŕé ţĥé ŵöŕķšþàçé ļîṽéš. -
Ţĥé đŕîṽéŕ'š þŕöƒîļé.
storage.DriverProfile()ŕéþöŕţš öñé çöññéçţîöñ þéŕ ƒîļé, ñö ŴÀĻ àñđ ñö çŕöšš-þŕöçéšš ļöçķ, àñđ đüŕàƃîļîţý ŵĥéñ ţĥé ƃŕîđĝé šàýš îţš đàţàƃàšéš öüţļîṽé ţĥé þàĝé (__kapiSQL.durable). Ţĥé ƃüšý ţîḿéöüţ îš žéŕö: à šéçöñđ çöññéçţîöñ'š ŵàîţ ŵöüļđ šþîñ ţĥé öñļý ţĥŕéàđ, šö à ļöçķ çöñƒļîçţ ŕéþöŕţšdatabase is lockedàţ öñçé. Çöđé öñ ţĥéšé þööļš ñéṽéŕ ĥöļđš à ţŕàñšàçţîöñ öŕ öþéñ ŕöŵš àñđ ţĥéñ ŵàîţš ƒöŕ à šéçöñđ šéššîöñ öñ ţĥé šàḿé þööļ ƒŕöḿ ţĥé šàḿé ĝöŕöüţîñé. Ţĥé ƃļöçķ šţöŕé'š îţéŕàţöŕš ŕéàđ à þàĝé àţ à ţîḿé àñđ ŕéļéàšé ţĥé çöññéçţîöñ ƃéƒöŕé ýîéļđîñĝ, šö à çàļļéŕ ḿàý ŵŕîţé ŵĥîļé îţ îţéŕàţéš. À ƒàîļéđCOMMITîš ŕöļļéđ ƃàçķ, àš ţĥé ñàţîṽé đŕîṽéŕ đöéš, šö ţĥé þööļ'š öñé çöññéçţîöñ ñéṽéŕ šţàýš îñšîđé à ţŕàñšàçţîöñ.make test-stores-oneconnŕüñš ţĥé šţöŕé šüîţéš ñàţîṽéļý ŵîţĥ éṽéŕý þööļ ĥéļđ ţö öñé çöññéçţîöñ àñđ ŴÀĻ öƒƒ, ţö ƒîñđ šüçĥ çöđé ŵîţĥöüţ à ƃŕöŵšéŕ: à çàļļ ţĥàţ ŵàîţš 20 šéçöñđš ƒöŕ ţĥé þööļ þàñîçš ŵîţĥ éṽéŕý ĝöŕöüţîñé'š šţàçķ, àñđ à ŕéàđ öñ öñé þööļ ƃéšîđé à ŵŕîţé ţĥé šàḿé çöđé ĥöļđš öñ àñöţĥéŕ ŵàîţš öüţ ţĥé ƃüšý ţîḿéöüţ àñđ ƒàîļš ŵîţĥdatabase is locked, ŵĥîçĥ ţĥé ƃŕöŵšéŕ ŕéþöŕţš àţ öñçé. ÇÎ ŕüñš îţ ƃéšîđémake test-wasm-stores, àñđ öñ þüšĥ ŕüñš ţĥé ĥöšţ šüîţé ţĥé šàḿé ŵàý (make test-host-oneconn). -
Đàţàƃàšé ƒîļéš ƃéļöñĝ ţö ţĥé đŕîṽéŕ. Ţĥé þàĝé'š ƒîļé šýšţéḿ ñéṽéŕ šééš à đàţàƃàšé, šö çöđé ţĥàţ àšķš ŵĥéţĥéŕ öñé éẋîšţš, ŕéḿöṽéš, ŕéñàḿéš öŕ ļîšţš ţĥéḿ çàļļš
storage.Exists,storage.Remove,storage.Rename,storage.Listàñđstorage.RemoveAllŕàţĥéŕ ţĥàños. À đàţàƃàšé'š đîŕéçţöŕý šţîļļ ĥàš ţö éẋîšţ îñ ţĥé éñĝîñé'š ƒîļé šýšţéḿ, àš îţ đöéš ñàţîṽéļý. -
À đàţàƃàšé ƒîļé à þàĝé àđđš. À ŠǪĻîţé ƒîļé îñ ţĥé éñĝîñé'š ƒîļé šýšţéḿ (öñé à ŕéàđéŕ üþļöàđš, šàý) îš ŕéàđ îñţö ḿéḿöŕý ţĥé ƒîŕšţ ţîḿé à šţöŕé öþéñš îţš þàţĥ, ţĥŕöüĝĥ
sqlite3_deserialize, àñđ ŵŕîţéš ĝö ţö ţĥé çöþý îñ ḿéḿöŕý. Ţĥé ñàḿéšþàçé àñšŵéŕš ƒöŕ šüçĥ ƒîļéš ţöö, àñđstorage.Removeđéļéţéš ţĥé ƒîļé ŵîţĥ ţĥé đàţàƃàšé, šö à ŕéḿöṽéđ đàţàƃàšé šţàýš ŕéḿöṽéđ. À ƒîļé ţĥàţ îš ñöţ à đàţàƃàšé ƒàîļš ţö öþéñ ŵîţĥfile is not a database, àš îţ đöéš ñàţîṽéļý; öñé ŵîţĥ àñ üñƒļüšĥéđ ŵŕîţé-àĥéàđ ļöĝ ƃéšîđé îţ ƒàîļš ŵîţĥ à ḿéššàĝé ţĥàţ šàýš šö. -
Ŕöŵ ƃàţçĥéš. À ǫüéŕý'š ŕöŵš çŕöšš 256 àţ à ţîḿé, öŕ àƃöüţ 1 ḾîƂ àţ à ţîḿé ŵĥéñ ţĥéý àŕé ļàŕĝé.
-
Ŵöŕđ šéàŕçĥ. Ţĥé ḿöđüļé çàŕŕîéš ŠǪĻîţé'š ƃüîļţ-îñ ƑŢŠ5 ţöķéñîžéŕš àñđ ñö ÎÇÜ, šö
storage.FTSWordTokenizerîšunicode61. -
Ţĥé àššéţ.
sqlite3.wasmîš šéŕṽéđ ƃéšîđé ţĥé éñĝîñé ƃîñàŕý, ŵĥéŕémake web-wasm-clišţàĝéš îţ (ŵîţĥsqlite3.wasm.gz) ƒŕöḿ ţĥé þîññéđ þàçķàĝé, àñđ ţĥé ƃööţ þŕéƒéŕš ţĥé þŕéçöḿþŕéššéđ çöþý.bootKapiRuntime(wasmExecUrl, wasmUrl, { sqliteWasmUrl })ţàķéš àñöţĥéŕ ļöçàţîöñ. Ḿéàšüŕéđ ŵîţĥ ĝžîþ -9, ţĥé àššéţ îš àƃöüţ 0.40 ḾƂ àñđ ţĥé ƃüñđļéđ ĴàṽàŠçŕîþţ (ţĥé ḿöđüļé'š ĝļüé àñđ ţĥé ƃŕîđĝé, ḿîñîƒîéđ) àƃöüţ 0.07 ḾƂ. -
Ţĥé ļàƃ þŕöĵéçţ. Ţĥé ŕéàđ-öñļý àññöţàţöŕš ƃéĥîñđ
labInspectAnnotatedļööķ ţéŕḿš üþ îñ à þŕöĵéçţ ţĥé éñĝîñé çŕéàţéš àţ/.lab/projectöñ ƒîŕšţ üšé, àñđ öþéñš àĝàîñ îƒ à ŕéšéţ çļöšéđ îţ. Îţš ţéŕḿš àŕé ţĥé ƃüñđļé îñkapi/cmd/kapi-wasm-cli/fixtures/terms.json, îḿþöŕţéđ ţĥŕöüĝĥ ţĥé þŕöĵéçţöŕ, šö ţĥéý àŕé öþéŕàţîöñš îñ ţĥé ŵöŕķšþàçé ļöĝ àš ţĥéý ŵöüļđ ƃé ñàţîṽéļý. Çöḿḿàñđš ţýþéđ îñ à ļàƃ ŕéšöļṽé šţöŕéš àš ñàţîṽéļý: îñšîđé à þŕöĵéçţ ţĥéý üšé ţĥé þŕöĵéçţ'š, àñđ öüţšîđé öñé ţĥé šţàñđàļöñé šţöŕé à ƒļàĝ öŕ ţĥé ŵöŕķîñĝ đîŕéçţöŕý ñàḿéš. -
Šţàŕţîñĝ à đîŕéçţöŕý öṽéŕ.
kapiReset(dir)ƒöŕĝéţš éṽéŕý þŕöĵéçţ çĥéçķéđ öüţ àţ öŕ ƃéļöŵdirîñ ţĥé ŵöŕķšþàçé (App.ForgetProjectsUnder, ŵĥîçĥ çļöšéš ţĥé šţöŕéš îţ ĥöļđš ţĥéŕé, ŕéàđš ţĥé ŕéĝîšţŕý ƒöŕ ţĥé þŕöĵéçţš à þŕéṽîöüš þàĝé ŕéĝîšţéŕéđ ţĥéŕé, àñđ çàļļšworkspace.Forgetƒöŕ éàçĥ), ţĥéñ ŕéḿöṽéš éṽéŕý đàţàƃàšé ţĥéŕé öüţšîđé ţĥé ŵöŕķšþàçé'š öŵñ. À þŕöĵéçţ šééđéđ ţĥéŕé àĝàîñ ƃéĝîñš ŵîţĥ àñ éḿþţý çöñţéẋţ àñđ àñ éḿþţý ŕéçöŕđ, ƃéçàüšé ţĥé þŕöĵéçţöŕ ŕéþļàýš, àñđ ţĥé çöñţéẋţ ļéđĝéŕ ŕéþöŕţš, öñļý ŵĥàţ ţĥé ļöĝ ĥöļđš àƒţéŕ à þŕöĵéçţ'š ļàţéšţ ŕéḿöṽàļ. À þŕöĵéçţ îš ķéýéđ ƃý îţš ŕéçîþé'šid:öŕname:, šö ţĥé šàḿé šàḿþļé šééđéđ îñ ţŵö đîŕéçţöŕîéš îš öñé þŕöĵéçţ ŵîţĥ öñé çöñţéẋţ, àñđ à ŕéšéţ üñđéŕ éîţĥéŕ đîŕéçţöŕý ƒöŕĝéţš îţ ŵĥöļé: ţĥé ļéàŕñîñĝ ļàƃš ŕéšéţ ţĥéîŕ ŵĥöļé/learnţŕéé öñ Þļàý ƒöŕ ţĥàţ ŕéàšöñ.KapiRuntime.reset(dir)çàļļš îţ àñđ ţĥéñ çļéàŕš ţĥé đîŕéçţöŕý'š ƒîļéš; ţĥé þļàýĝŕöüñđ'š Ŕéšéţ ƃüţţöñ àñđ ţĥé ţéŕḿîñàļ'šrm(ţĥŕöüĝĥKapiRuntime.removeDatabase) üšé ţĥéḿ. -
Ţéšţéđ îñ Ñöđé.
make test-wasm-storesŕüñš ţĥé šţöŕé šüîţéš üñđéŕGOOS=jsîñ Ñöđé öṽéŕ ţĥé šàḿé ƃŕîđĝé (scripts/wasm-stores/), àñđ ţĥé çĥàñĝé šéŕṽîçé'š šüîţéš ƃéšîđé ţĥéḿ (Ţĥé çĥàñĝé çöñţŕàçţ). À ţéšţ ţĥàţ ñééđš à šüƃþŕöçéšš (ĝîţ, öŕ à šéçöñđ ŵŕîţéŕ þŕöçéšš), đîŕéçţöŕý þéŕḿîššîöñš ţĥàţ ŕéàçĥ à đàţàƃàšé, öŕ þŕééḿþţîöñ šķîþš ţĥéŕé àñđ ñàḿéš ŵĥîçĥ.
Ţĥé çĥàñĝé çöñţŕàçţ
À þàĝé ţĥàţ éđîţš çöñţéñţ šéñđš ţĥé çĥàñĝé çöñţŕàçţ
(É-09) ţö ţĥŕéé
éñţŕý þöîñţš, ŕàţĥéŕ ţĥàñ à çöḿḿàñđ ļîñé ţö kapiRun. Éàçĥ ţàķéš ţĥé
çöñţŕàçţ'š ĴŠÖÑ àš à šţŕîñĝ àñđ àñ öþţîöñàļ šéçöñđ šţŕîñĝ, ţĥé çàļļ'š öþţîöñš,
àñđ ŕéţüŕñš à Þŕöḿîšé öƒ à ĴŠÖÑ šţŕîñĝ.
| Éñţŕý þöîñţ | Ţàķéš | Ŕéšöļṽéš ţö |
|---|---|---|
kapiRead(requestJSON, optionsJSON?) | à ŕéàđ ŕéǫüéšţ: {doc, blocks, editions, cursor, limit} | à ŕéàđ þàĝé: éàçĥ ƃļöçķ'š ref àñđ rev, îţš ţéẋţ îñ þļàçéĥöļđéŕ ƒöŕḿ, îţš çöđéš, þļüŕàļš àñđ šéļéçţš, îţš öţĥéŕ éđîţîöñš àñđ ţĥé öþéŕàţîöñš îţ àççéþţš, àñđ next ƒöŕ ţĥé ƒöļļöŵîñĝ þàĝé |
kapiApply(changeSetJSON, optionsJSON?) | à kapi.change/v1 çĥàñĝé šéţ: àñ öƃĵéçţ ŵîţĥ ops, ĴŠÖÑĻ, öŕ àñ àŕŕàý öƒ öþéŕàţîöñš | ţĥé kapi.change-result/v1 ŕéšüļţ |
kapiDescribe(requestJSON, optionsJSON?) | {format} öŕ {doc} | ŵĥàţ ţĥé ƒöŕḿàţ šüþþöŕţš öƒ éàçĥ öþéŕàţîöñ |
- Öþţîöñš.
{project, actor}.projectñàḿéš ţĥé þŕöĵéçţ ţĥé çàļļ àçţš îñ: îţškapi.yaml, îţš ŕööţ, öŕ à þàţĥ îñšîđé îţ. Ŵîţĥöüţ öñé, ţĥé çàļļ àçţš îñ ţĥé þŕöĵéçţ đîšçöṽéŕý ƒîñđš ƒŕöḿ ţĥé éñĝîñé'š ŵöŕķîñĝ đîŕéçţöŕý, àš à çöḿḿàñđ ĝîṽéñ ñö-pđöéš, àñđ öüţšîđé àñý þŕöĵéçţ à đöçüḿéñţ îš à þàţĥ üñđéŕ ţĥàţ đîŕéçţöŕý.actor, ŵĥîçĥ öñļý àñ àþþļý ţàķéš, îš{kind, name, session}ŵîţĥkindéîţĥéŕpersonöŕagent. Ŵîţĥöüţ öñé, ţĥé šéñđéŕ îš ţĥé öñékapi applyŕéçöŕđš îñ ţĥé šàḿé éñṽîŕöñḿéñţ: à þéŕšöñ, üñļéššKAPI_ACTORöŕ àñ àĝéñţ ĥöšţ'š ḿàŕķéŕ šàýš öţĥéŕŵîšé. Àñ àĝéñţ'š ţéŕḿ, ḿéḿöŕý àñđ ŕéçîþé öþéŕàţîöñš, îţš đéçîšîöñš öţĥéŕ ţĥàñ à þŕé-ŕéṽîéŵ (advise), àñif_matchöƒ*àñđ ţĥéreportĝàţé àŕé ŕéƒüšéđ àšnot_permitted, àš ţĥéý àŕé öṽéŕ ḾÇÞ. - Öñé šéŕṽîçé. Ţĥé çàļļš ƃüîļđ ţĥé çĥàñĝé šéŕṽîçé ţĥŕöüĝĥ
host.ReadChangesJSON,host.ApplyChangesJSONàñđhost.DescribeChangesJSON, ƒŕöḿ ţĥé šàḿé ƒüñçţîöñ ţĥé ḾÇÞ éđîţ ţööļš üšé (callChangeService), ŵîţĥ ţĥé çöḿḿîţ çĥéçķ, ţĥé þöļîçý àñđ ţĥé ŕéçöŕđéŕkapi applyŕüñš. À ŕéƒéŕéñçé àñđ à ŕéṽîšîöñ ţĥàţkapiReadŕéţüŕñš àŕé ţĥé öñéškapi inspectþŕîñţš ƒöŕ ţĥé šàḿé ƒîļé, àñđkapiApplyţàķéš éîţĥéŕ. À ƃîļîñĝüàļ ƒîļé ŵĥöšé ŕéàđéŕ ĥàš ţö ƃé ţöļđ ţĥé ļàñĝüàĝé öƒ ţĥé ţŕàñšļàţîöñ îţ ĥöļđš, šüçĥ àš à ÞÖ çàţàļöĝ'šmsgstr, îš ŕéàđ îñ ţĥé öñé ļàñĝüàĝé öţĥéŕ ţĥàñ ţĥé šöüŕçé ţĥàţ à ŕéàđ'šeditionsöŕ àñ àþþļý'š öþéŕàţîöñš ñàḿé, àškapi applyŕéàđš öñé. - Àñšŵéŕš. À ŕéǫüéšţ ţĥé šéŕṽîçé ŕéƒüšéš, à çĥàñĝé šéţ ţĥàţ đöéš ñöţ
đéçöđé îñçļüđéđ, ŕéšöļṽéš ţö à
kapi.change-result/v1ŵĥöšéerroršàýš ŵĥý. Ţĥé Þŕöḿîšé ŕéĵéçţš öñļý ƒöŕ à ƒàîļüŕé ţĥé çöñţŕàçţ ĥàš ñö çöđé ƒöŕ, šüçĥ àš àprojectţĥàţ ñàḿéš ñö ƒîļé. Öñ ţĥé ƒàçàđé,readàñđdescribeţĥŕöŵChangeRefused, ŵĥîçĥ çàŕŕîéš ţĥàţ ŕéšüļţ, àñđapplyŕéšöļṽéš ţö îţš ŕéšüļţ ŵĥàţéṽéŕ ţĥé šţàţüš. - Ţĥé ŕéçöŕđ. Îñ à þŕöĵéçţ, àñ àþþļîéđ çĥàñĝé šéţ îš ŕéçöŕđéđ îñ ţĥé
ŵöŕķšþàçé'š ļöĝ üñđéŕ
/.kapi-dataàš öñécontent.editöþéŕàţîöñ þéŕ đöçüḿéñţ, ţĥé ŕéçöŕđkapi applyŵŕîţéš ñàţîṽéļý, àñđ ţĥé þŕöĵéçţöŕ ŵŕîţéš îţ îñţö ţĥé ƃļöçķ ĥîšţöŕý. À ļàţéŕ ŕéàđ šĥöŵš à ţŕàñšļàţîöñ'š ƃàšîš ƒŕöḿ ţĥéŕé. Öüţšîđé à þŕöĵéçţ ñöţĥîñĝ îš ŕéçöŕđéđ. Éṽéŕý éđîţ îš ķéþţ ŵîţĥ ţĥé ŕéšţ öƒ ţĥé ŵöŕķšþàçé (Šţöŕàĝé). - Öñé àţ à ţîḿé. Ţĥé çàļļš, ţĥé çöḿḿàñđš
kapiRunŕüñš (à çöḿþļéţîöñ îñçļüđéđ) àñđkapiResetšĥàŕé ţĥé éñĝîñé'š Àþþ, šö ţĥé éñĝîñé ŕüñš ţĥéḿ îñ ţüŕñ: à çöḿḿàñđ šţàŕţéđ ŵĥîļé à çàļļ ŕüñš ŵàîţš ƒöŕ îţ, àñđ ţĥé öţĥéŕ ŵàý ŕöüñđ. À çöḿḿàñđ ŕéþļàçéš ţĥé Àþþ'š çöñƒîĝüŕàţîöñ àñđ à ŕéšéţ ŕéḿöṽéš đàţàƃàšéš, šö ñéîţĥéŕ ḿàý ŕüñ ŵĥîļé à çàļļ ŵàîţš öñ ţĥé ƒîļé šýšţéḿ. À çàļļ ţàķéš îţš þŕöĵéçţ ƒŕöḿ îţš öþţîöñš àñđ îţš šöüŕçé ļàñĝüàĝé ƒŕöḿ ţĥàţ þŕöĵéçţ, ñöţ ƒŕöḿ ţĥé ƒļàĝš à çöḿḿàñđ ŵàš ĝîṽéñ. Ţŵö ŵŕîţéŕš öƒ öñé ƒîļé îñ ţĥé þàĝé šţîļļ ţàķé ţüŕñš àţ ţĥé çöḿḿîţ: ţĥé ƒîļé ĥöḿé'š ļöçķ (core/storage/filelock) îš à ḿüţéẋ öƒ ţĥé þŕöçéšš ŵĥéŕé ţĥé þļàţƒöŕḿ ĥàš ñö ļöçķ ƃéţŵééñ þŕöçéššéš. - Ţéšţéđ.
make test-wasm-storesŕüñš, üñđéŕGOOS=jsöṽéŕ ţĥé ƃŕöŵšéŕ'š ŠǪĻîţé đŕîṽéŕ,core/changeàñđ îţš ƒîļé ĥöḿé ŵîţĥ ţĥé çöñƒöŕḿàñçé šüîţé (core/change/changetest), ţĥé ļöçķ, ţĥé ĥöšţ'š šéŕṽîçé ƒöŕ à þŕöĵéçţ ţĥŕöüĝĥ ţĥé šàḿé šüîţé àñđ îţš ĴŠÖÑ éñţŕý þöîñţš, àñđ ţĥé éñĝîñé'š öŵñ ţéšţ öƒ ţĥé öŕđéŕ îţš éñţŕý þöîñţš ţàķé ţüŕñš îñ.make change-wasm-smoke(scripts/verify-snippets/change-smoke.ts) ƃööţš ţĥé ŕéàļ éñĝîñé îñ Ñöđé àñđ đŕîṽéš ţĥé ţĥŕéé çàļļš ţĥŕöüĝĥ ţĥé ƒàçàđé: à ŕéàđ ţĥàţ ḿàţçĥéškapi inspect, àñ éđîţ ţĥàţ ļàñđš ƃýţé ƒöŕ ƃýţé àñđ îš ŕéçöŕđéđ, à šţàļé ŕéþļàý, à ţŕàñšļàţîöñ'š ƃàšîš ŕéàđ ƃàçķ, àñđ ţĥé ŕéƒüšàļš.
Çöḿḿàñđ šüŕƒàçé
kapiRun(argv) éẋéçüţéš ţĥé öŕđîñàŕý ķàþî ÇĻÎ, šö ţĥé ƃŕöŵšéŕ ƃüîļđ ĥàš à
šéçöñđ çöñţŕàçţ àļöñĝšîđé ţĥé ĝļöƃàļ ƒüñçţîöñ šéţ: ŵĥîçĥ ṽéŕƃš îţ àñšŵéŕš.
kapi apply àñđ kapi inspect ŕüñ ţĥéŕé àš ţĥéý đö ñàţîṽéļý, öṽéŕ ţĥé šàḿé
šéŕṽîçé àš ţĥé çĥàñĝé çöñţŕàçţ'š éñţŕý þöîñţš.
- Öñé đéçļàŕàţîöñ.
cli.BrowserCommandSetîš ţĥé ƃŕöŵšéŕ ƃüîļđ'š çöḿḿàñđ šéţ, ḿîŕŕöŕîñĝcli.KapiCommandSet(ţĥé ñàţîṽé ƃîñàŕý'š) ṽéŕƃ ƒöŕ ṽéŕƃ.kapi/cmd/kapi-wasm-cliŕéĝîšţéŕš îţ ŵĥöļéšàļé àñđ đéçļàŕéš ñöţĥîñĝ îţšéļƒ. - Ñö ḿîššîñĝ ṽéŕƃš. À ṽéŕƃ ţĥé ƃŕöŵšéŕ çàññöţ ŕüñ (öñé ñééđîñĝ à
šüƃþŕöçéšš, ţĥé ÖŠ ķéýçĥàîñ, ţĥé ñéţŵöŕķ, öŕ à šöçķéţ) îš ŕéçöŕđéđ îñ
cli.browserGapsŵîţĥ ţĥé ƒàçîļîţý îţ ñééđš, àñđ ŕéĝîšţéŕš à çöḿḿàñđ ţĥàţ ŕéþöŕţš îţ.unknown commandţĥéŕéƒöŕé ḿéàñš ţĥé ṽéŕƃ đöéš ñöţ éẋîšţ îñ ķàþî àţ àļļ, ñéṽéŕ ţĥàţ ţĥé ƃŕöŵšéŕ öḿîţţéđ îţ.--helpšţîļļ ŵöŕķš öñ ţĥöšé ṽéŕƃš; ţĥéîŕ ĥéļþ ţéẋţ çàŕŕîéš ţĥé ļîḿîţàţîöñ. - Ñö ḾÇÞ šéŕṽéŕ.
kapi mcpîš à ŕéçöŕđéđ ĝàþ, àñđ ţĥé ƃüîļđ ļéàṽéš ţĥé šéŕṽéŕ öüţ éñţîŕéļý: ţĥé ĥöšţ àñđ çļî ƒîļéš ţĥàţ îḿþöŕţ ţĥé ḾÇÞ ŠĐĶ àŕé ƃüîļţ ŵîţĥ//go:build !js, šö ñéîţĥéŕ ţĥé ŠĐĶ ñöŕ à ţööļ îţ ŵöüļđ šéŕṽé ŕéàçĥéš ţĥé éñĝîñé.host/mcp_js.goàñđcli/mcp_js.gošţàñđ îñ ƒöŕ ţĥé ƒéŵ ñàḿéš ţĥé ŕéšţ öƒ ţĥé ƃüîļđ üšéš.make test-wasm-storesçöḿþîļéš ţĥé ĥöšţ'š ţéšţš ƒöŕ ţĥé ƃŕöŵšéŕ, šö à ĥöšţ ţéšţ ţĥàţ đŕîṽéš àñ ḾÇÞ ţööļ šîţš îñ à ƒîļé ƃüîļţ ŵîţĥ!js: ţĥémcp_*_test.goƒîļéš, àñđ ţĥé*_mcp_test.goƒîļéš ƃéšîđé ţĥé ţéšţš ţĥéý ƃéļöñĝ ŵîţĥ. - Ñö þļüĝîñ ĥöšţ.
kapi pluginîš à ŕéçöŕđéđ ĝàþ: à þļüĝîñ îš à šéþàŕàţé éẋéçüţàƃļé ţĥàţ ķàþî šţàŕţš àš à šüƃþŕöçéšš àñđ ŕéàçĥéš öṽéŕ ĝŔÞÇ, àñđ à þàĝé çàñ đö ñéîţĥéŕ. Ţĥéhost/pluginhostƒîļéš ţĥàţ šţàŕţ à þļüĝîñ öŕ ţàļķ ţö öñé (ţĥé đàéḿöñ þööļ, ţĥé ĝŔÞÇ çļîéñţš ƒöŕ ƒöŕḿàţš, šéĝḿéñţéŕš, çöḿḿéñţš àñđ šöüŕçé çöññéçţöŕš, ţĥé šüƃþŕöçéšš ļàüñçĥéš) àŕé ƃüîļţ ŵîţĥ//go:build !js, šö ĝŔÞÇ àñđ ţĥé þļüĝîñ þŕöţöƃüƒ šţàý öüţ öƒ ţĥé éñĝîñé. Đîšçöṽéŕý àñđ ţĥé ḿàñîƒéšţ-đŕîṽéñ ĥöšţ ƃüîļđ ƒöŕ ţĥé ƃŕöŵšéŕ àš ŵéļļ, àñđhost/pluginhost/runtime_js.gošţàñđš îñ ƒöŕ ţĥé ļàüñçĥéš ţĥé ŕéšţ öƒ ţĥé ƃüîļđ ñàḿéš, éàçĥ àñšŵéŕîñĝ ţĥàţ ţĥé ƃŕöŵšéŕ ŕüñš ñö þļüĝîñ. À ţéšţ ţĥàţ đŕîṽéš ţĥé þļüĝîñ ŵîŕé šîţš îñ à ƒîļé ƃüîļţ ŵîţĥ!js. - Đŕîƒţ îš à ţéšţ ƒàîļüŕé.
cli.TestBrowserCommandSurfaceçöḿþàŕéš ţĥé ţŵö šéţš àñđ ƒàîļš ŵĥéñ à ṽéŕƃ àþþéàŕš îñ öñé àñđ ñöţ ţĥé öţĥéŕ, öŕ ŵĥéñ à ĝàþ'š ĥéļþ ḿéţàđàţà đŕîƒţš ƒŕöḿ ţĥé çöḿḿàñđ îţ šţàñđš îñ ƒöŕ. Àđđîñĝ à ṽéŕƃ ţöKapiCommandSetîš à đéçîšîöñ: ŵîŕé îţ üþ ƒöŕ ţĥé ƃŕöŵšéŕ, öŕ ŕéçöŕđ ŵĥý îţ çàññöţ ŕüñ ţĥéŕé. - Ŕüñţîḿé ĝüàŕđ.
make wasm-surface-smoke(scripts/verify-snippets/command-surface-smoke.ts) ƃööţš ţĥé ŕéàļ ŵàšḿ îñ Ñöđé, šŵééþš éṽéŕý ŕéàçĥàƃļé ṽéŕƃ ƒöŕunknown command, àššéŕţš éàçĥ ĝàþ'š ḿéššàĝé, àñđ ŕéþļàýš ţĥé àŕĝṽ ţĥé ļàƃ éẋþļöŕéŕš ţĥéḿšéļṽéš üšé. Îţ ŕüñš îñ ţĥé đöçš šñîþþéţ-ṽéŕîƒîçàţîöñ ŵöŕķƒļöŵ (docs-verify-snippets.yml). - Çàþţüŕé šţŕîþš ÀÑŠÎ. Ţĥé éñĝîñé ƃööţš ŵîţĥ
CLICOLOR_FORCE=1šö ţĥé þļàýĝŕöüñđ ţéŕḿîñàļ ŕéñđéŕš ķàþî'š ŕéàļ šţýļîñĝ;runCaptureĥàñđš öüţþüţ ţö þŕöĝŕàḿ çöđé îñšţéàđ, àñđ šţŕîþš ţĥé éšçàþéš šö à--jsonþàýļöàđ þàŕšéš.
Ţĥé šàḿé đéŕîṽàţîöñ ƒééđš ţĥé đöçš: scripts/gen-refs ŕéàđš
cli.BrowserUnavailableReason ƒöŕ éàçĥ çöḿḿàñđ'š ŕüññàƃļé-îñ-ƃŕöŵšéŕ ƃàđĝé, šö
ţĥé Çöḿḿàñđ Ŕéƒéŕéñçé çàññöţ çļàîḿ à ṽéŕƃ ŕüñš îñ ţĥé ļàƃ ŵĥéñ îţ đöéš ñöţ.
Ŵĥéŕé ţĥé þîéçéš ļîṽé
| Çöñçéŕñ | Ļöçàţîöñ |
|---|---|
Ŕéĝîšţŕàţîöñ ţàƃļé + kapiEngineABI() | kapi/cmd/kapi-wasm-cli/main.go |
| Ƃŕöŵšéŕ çöḿḿàñđ šéţ + ŕéçöŕđéđ ĝàþš | cli/browsercmds.go |
| Šüŕƒàçé đŕîƒţ ĝüàŕđ | cli/browsercmds_test.go |
| Ŕüñţîḿé šüŕƒàçé šḿöķé | scripts/verify-snippets/command-surface-smoke.ts |
| Àḿƃîéñţ ŢŠ ţýþîñĝš ƒöŕ ţĥé ĝļöƃàļš | packages/engine/src/globals.ts |
Ŵîŕé šĥàþéš + engineABI() ĥéļþéŕ | packages/engine/src/abi.ts |
KapiRuntime ƒàçàđé + ƃööţ | packages/engine/src/runtime.ts |
ŠǪĻîţé ƃŕîđĝé (__kapiSQL) | packages/engine/src/sqlite.ts |
| Ţĥé éñĝîñé'š Ŵöŕķéŕ àñđ îţš ḿéššàĝéš | packages/engine/src/worker.ts, packages/engine/src/protocol.ts |
| Ŵĥéŕé ţĥé ŵöŕķšþàçé îš ķéþţ (þööļ, Ŵéƃ Ļöçķ, ƒîļé šţöŕé) | packages/engine/src/storage.ts |
Ĥàñđîñĝ ţĥé ŵöŕķšþàçé ƃéţŵééñ ţàƃš (takeOver, lost) | packages/engine/src/runtime.ts, packages/engine/src/worker.ts |
| Ļöçķš ƃéţŵééñ çöññéçţîöñš öñ ţĥé þööļ | packages/engine/src/locks.ts |
Ŵöŕķšþàçé éẋþöŕţ àñđ îḿþöŕţ (kapiExportWorkspace, kapiImportWorkspace) | kapi/cmd/kapi-wasm-cli/workspace.go, kpz/workspacepkg.go |
| Àñ öþéŕàţîöñ ĥéļđ ƃéƒöŕé îţš þŕöĵéçţ'š ŕéḿöṽàļ | core/workspace/local.go (Record), core/workspace/sync.go |
Šýñç ţĥŕöüĝĥ à ƒöļđéŕ (kapiSyncContext) | kapi/cmd/kapi-wasm-cli/contextremote.go, packages/engine/src/folderremote.ts, host/contextsync.go |
| Þéŕšîšţéñçé šḿöķé (ŕéļöàđ, ŕéšţàŕţ, à ţàķéöṽéŕ, à ŵàîţîñĝ ţàƃ, à ŕéšéţ àñđ ŕé-îḿþöŕţ, à ƒöļđéŕ šýñç, àñ éẋþöŕţ) | scripts/wasm-persist/, make wasm-persist-smoke |
| Ƃŕöŵšéŕ đàţàƃàšé đŕîṽéŕ + þŕöƒîļé + ñàḿéšþàçé | core/storage/driver_js.go, core/storage/sqlitejs_js.go |
Šţöŕé šüîţéš üñđéŕ GOOS=js | scripts/wasm-stores/, make test-wasm-stores |
| Ļàƃ þŕöĵéçţ ƒöŕ ţĥé àññöţàţöŕš | kapi/cmd/kapi-wasm-cli/labproject.go |
Šţàŕţîñĝ à đîŕéçţöŕý öṽéŕ (kapiReset) | kapi/cmd/kapi-wasm-cli/reset.go, App.ForgetProjectsUnder îñ host/projectstore.go |
Ţĥé çĥàñĝé çöñţŕàçţ (kapiRead, kapiApply, kapiDescribe) | kapi/cmd/kapi-wasm-cli/changes.go, host/changes_call.go |
| Ţĥé çĥàñĝé çöñţŕàçţ šḿöķé | scripts/verify-snippets/change-smoke.ts, make change-wasm-smoke |
| Ŕéṽéŕšé-ƃŕîđĝé çàþàƃîļîţý ţýþéš | packages/engine/src/capabilities.ts |
| Þàýļöàđ ţýþéš (ÇöñţéñţŢŕéé, ŕüñš, ţĥé çĥàñĝé çöñţŕàçţ) | @neokapi/contract-types (ĝéñéŕàţéđ) |
Ŵĥéñ àđđîñĝ àñ éñţŕý þöîñţ: àđđ îţ ţö engineExports, ţýþé îţ îñ
globals.ts, šüŕƒàçé îţ öñ ţĥé ƒàçàđé îƒ üšéŕ-ƒàçîñĝ, àñđ ļéàṽé ţĥé abi
ṽàļüé àļöñé (àđđîţîöñš đöñ'ţ ƃüḿþ îţ).