mirror of
https://github.com/stablyai/orca.git
synced 2026-09-23 00:02:29 +00:00
* perf(startup): stop queueing window creation behind the proxy apply and i18n
Three independent, measured startup wins, all free:
1. Park the initial Chromium proxy apply on `mainProcessState` instead of
awaiting it mid-`initializeReadyFoundation`. `setProxy` still starts at the
identical moment; the default-session request guard (which holds, not
cancels) is what actually fences fetchers on it, so only window creation
stops waiting. Runtime launch still awaits it before the desktop relay and
before every headless-serve fetcher.
2. Run `initializeMainProcessI18nAndMenu` concurrently with
`initializeMainProcessRuntimeLaunch`. Nothing in window creation reads a
translated string or the native menu.
3. Load `emojibase-data` in main through `createRequire` on first use instead
of a static import, keeping 166 KB of JSON off `out/main/index.js` and its
~2 ms parse off every launch. The renderer keeps its eager copy unchanged.
out/main/index.js 7,210,071 -> 7,040,147 bytes. No renderer behaviour changes.
* fix(packaging): ship the emoji shortcode dataset main lazily requires
app.asar carries no node_modules, so main's bare requires resolve only out of
Resources/node_modules. emojibase-data is a devDependency and is not in the
packaged runtime allowlist, so the new createRequire in
deferred-emoji-shortcode-dataset.ts threw MODULE_NOT_FOUND in every packaged
build — breaking sanitizeWorktreeName, and with it workspace creation.
Copy the single 166 KB dataset (not the 49 MB package root) into
Resources/node_modules, and gate every createRequire'd bare specifier in
src/main against the packaged resource plan. verifyPackagedMainRuntimeDeps
cannot catch these: the bundler renames the require binding.
* test(proxy): fail CI when a main-process fetcher escapes the default-session guard
The hoist relies on installElectronProxyRequestGuard(session.defaultSession) holding every app-owned request until the persisted proxy lands. Nothing enforced that every fetcher actually lands on defaultSession. Two source-anchored rules do now: no net.fetch/net.request may name a session/partition, and every non-net .fetch( call site is counted against an allowlist.
* test(proxy): close the shorthand and chained-receiver holes in the fetch call-site audit
The audit caught `net.request({ session: x })` and `ident.fetch(`, but not the two
shapes a real regression is just as likely to take: the `{ url, session }` shorthand
that both `net.request` overloads accept, and a receiver with no bare identifier
(`session.fromPartition(...).fetch(`, `ctx.session.fetch(`). Rule 1 now also matches
the shorthand key; rule 2 scans every `.fetch(` and excludes only a literal
`net`/`globalThis`/`global` receiver. Audited counts are unchanged (2/2/1).
* fix(startup): scope the deferred emoji loader to the projects that own it
TS6307: the composite web project lists src/main/ipc/worktree-logic.ts, which
now imports the deferred dataset loader, and the shared lazy test reached into
src/main from a project that has no src/main files. Add the loader to
tsconfig.tc.web.json and move the cross-project case into a src/main test.
Also close the last two review gaps: gate the runtime-RPC startup failure
dialog (the only launch-phase translateMain reader) on a published i18n
barrier so a concurrent i18n phase cannot leave a non-English user with the
English fallback, and let the fetch call-site audit match `net.fetch (url)`.
66 lines
2.8 KiB
TypeScript
66 lines
2.8 KiB
TypeScript
import { readFileSync } from 'node:fs'
|
|
import { join } from 'node:path'
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import emojiShortcodes from 'emojibase-data/en/shortcodes/emojibase.json'
|
|
|
|
async function importConfiguredCatalog() {
|
|
const catalog = await import('./emoji-shortcode-catalog.js')
|
|
catalog.setEmojiShortcodeDatasetLoader(() => emojiShortcodes)
|
|
return catalog
|
|
}
|
|
|
|
describe('emoji shortcode catalog laziness', () => {
|
|
beforeEach(() => {
|
|
vi.resetModules()
|
|
})
|
|
|
|
it('does not build the catalog when the shared module is imported', async () => {
|
|
const catalog = await importConfiguredCatalog()
|
|
|
|
expect(catalog.isEmojiShortcodeCatalogBuiltForTest()).toBe(false)
|
|
|
|
expect(catalog.getStandardEmojiShortcodeEntries().length).toBeGreaterThan(1000)
|
|
expect(catalog.isEmojiShortcodeCatalogBuiltForTest()).toBe(true)
|
|
})
|
|
|
|
it('builds on first use and keeps the main process off the eager path', async () => {
|
|
const catalog = await importConfiguredCatalog()
|
|
|
|
expect(catalog.replaceKnownEmojiWithShortcodes('ship \u{1F389}')).toBe('ship party ')
|
|
expect(catalog.isEmojiShortcodeCatalogBuiltForTest()).toBe(true)
|
|
})
|
|
|
|
it('leaves the main-process worktree namer importing only the deferred entry points', () => {
|
|
// A cross-project import would drag src/main into the shared tsconfig, so assert on source.
|
|
const worktreeLogic = readFileSync(join(__dirname, '../main/ipc/worktree-logic.ts'), 'utf8')
|
|
const catalogImport = worktreeLogic.match(
|
|
/import \{([^}]*)\} from '[^']*emoji-shortcode-catalog'/
|
|
)
|
|
|
|
expect(catalogImport?.[1].split(',').map((name) => name.trim())).toEqual([
|
|
'replaceKnownEmojiWithShortcodes',
|
|
'setEmojiShortcodeDatasetLoader'
|
|
])
|
|
})
|
|
|
|
it('keeps the catalog build out of module scope', () => {
|
|
const sharedSource = readFileSync(join(__dirname, 'emoji-shortcode-catalog.ts'), 'utf8')
|
|
|
|
// A module-scope `const X = <expression over the dataset>` is the regression this guards.
|
|
expect(sharedSource).not.toMatch(/^const \w+ = Object\.entries\(/m)
|
|
expect(sharedSource).not.toMatch(/^const \w+ = new (?:Map|Intl\.Segmenter)\(/m)
|
|
expect(sharedSource).toContain('function loadCatalog()')
|
|
})
|
|
|
|
it('keeps the 166 KB dataset off every module main statically imports', () => {
|
|
const sharedSource = readFileSync(join(__dirname, 'emoji-shortcode-catalog.ts'), 'utf8')
|
|
const worktreeLogic = readFileSync(join(__dirname, '../main/ipc/worktree-logic.ts'), 'utf8')
|
|
|
|
// A static `emojibase-data` import anywhere main reaches inlines the dataset into
|
|
// out/main/index.js and JSON.parses it on every launch.
|
|
const staticDatasetImport = /\bfrom '[^']*emojibase-data[^']*'/
|
|
expect(sharedSource).not.toMatch(staticDatasetImport)
|
|
expect(worktreeLogic).not.toMatch(staticDatasetImport)
|
|
})
|
|
})
|