fix: package of llama-node

This commit is contained in:
linonetwo 2023-07-17 16:44:40 +08:00 committed by lin onetwo
parent d60ae9d132
commit 66ea5a2c34
14 changed files with 104 additions and 56 deletions

View file

@ -5,22 +5,22 @@
"version": "0.8.1-prerelease1", "version": "0.8.1-prerelease1",
"license": "MPL 2.0", "license": "MPL 2.0",
"scripts": { "scripts": {
"start": "pnpm run clean && pnpm run start:without-clean", "start": "pnpm run clean && pnpm run init:git-submodule && pnpm run start:without-clean",
"start:without-clean": "pnpm run build:plugin && cross-env NODE_ENV=development electron-forge start", "start:without-clean": "pnpm run build:plugin && cross-env NODE_ENV=development electron-forge start",
"start:without-clean:debug-worker": "pnpm run build:plugin && cross-env NODE_ENV=development DEBUG_WORKER=true electron-forge start", "start:without-clean:debug-worker": "pnpm run build:plugin && cross-env NODE_ENV=development DEBUG_WORKER=true electron-forge start",
"start:without-clean:debug-main": "pnpm run build:plugin && cross-env NODE_ENV=development DEBUG_MAIN=true electron-forge start", "start:without-clean:debug-main": "pnpm run build:plugin && cross-env NODE_ENV=development DEBUG_MAIN=true electron-forge start",
"build:plugin": "zx scripts/compilePlugins.mjs", "build:plugin": "zx scripts/compilePlugins.mjs",
"test": "pnpm run clean && cross-env NODE_ENV=test pnpm run package && pnpm run test:without-package", "test": "pnpm run clean && cross-env NODE_ENV=test pnpm run package && pnpm run test:without-package",
"test:without-package": "mkdir -p logs && cross-env NODE_ENV=test cucumber-js", "test:without-package": "mkdir -p logs && cross-env NODE_ENV=test cucumber-js",
"package": "pnpm run init:git-submodule && pnpm run build:plugin && electron-forge package", "package": "pnpm run clean && pnpm run build:plugin && electron-forge package",
"make:mac-x64": "pnpm run init:git-submodule && pnpm run build:plugin && cross-env NODE_ENV=production electron-forge make --platform=darwin --arch=x64", "make:mac-x64": "pnpm run clean && pnpm run build:plugin && cross-env NODE_ENV=production electron-forge make --platform=darwin --arch=x64",
"make:mac-arm": "pnpm run init:git-submodule && pnpm run build:plugin && cross-env NODE_ENV=production electron-forge make --platform=darwin --arch=arm64", "make:mac-arm": "pnpm run clean && pnpm run build:plugin && cross-env NODE_ENV=production electron-forge make --platform=darwin --arch=arm64",
"make:win-x64": "pnpm run init:git-submodule && pnpm run build:plugin && cross-env NODE_ENV=production electron-forge make --platform=win32 --arch=x64", "make:win-x64": "pnpm run clean && pnpm run build:plugin && cross-env NODE_ENV=production electron-forge make --platform=win32 --arch=x64",
"make:win-ia32": "pnpm run init:git-submodule && pnpm run build:plugin && cross-env NODE_ENV=production electron-forge make --platform=win32 --arch=ia32", "make:win-ia32": "pnpm run clean && pnpm run build:plugin && cross-env NODE_ENV=production electron-forge make --platform=win32 --arch=ia32",
"make:win-arm": "pnpm run init:git-submodule && pnpm run build:plugin && cross-env NODE_ENV=production electron-forge make --platform=win32 --arch=arm64", "make:win-arm": "pnpm run clean && pnpm run build:plugin && cross-env NODE_ENV=production electron-forge make --platform=win32 --arch=arm64",
"make:linux-x64": "pnpm run init:git-submodule && pnpm run build:plugin && cross-env NODE_ENV=production electron-forge make --platform=linux --arch=x64", "make:linux-x64": "pnpm run clean && pnpm run build:plugin && cross-env NODE_ENV=production electron-forge make --platform=linux --arch=x64",
"make:linux-arm": "pnpm run init:git-submodule && pnpm run build:plugin && cross-env NODE_ENV=production electron-forge make --platform=linux --arch=arm64", "make:linux-arm": "pnpm run clean && pnpm run build:plugin && cross-env NODE_ENV=production electron-forge make --platform=linux --arch=arm64",
"clean": "rimraf ./out ./settings-dev ./node_modules/@tiddlygit/tiddlywiki/plugins/linonetwo ./cache-database-dev ./logs ./.webpack ./node_modules/.cache && cross-env NODE_ENV=development npx ts-node scripts/developmentMkdir.ts && pnpm run init:git-submodule", "clean": "rimraf -- ./out ./settings-dev ./node_modules/@tiddlygit/tiddlywiki/plugins/linonetwo ./cache-database-dev ./logs ./.webpack ./node_modules/.cache && cross-env NODE_ENV=development npx ts-node scripts/developmentMkdir.ts && rimraf -- ./out",
"init:git-submodule": "git submodule update --recursive && git submodule update --remote", "init:git-submodule": "git submodule update --recursive && git submodule update --remote",
"lint": "eslint ./src --ext js,ts,tsx,json", "lint": "eslint ./src --ext js,ts,tsx,json",
"lint:fix": "eslint ./src --ext js,ts,tsx,json --fix", "lint:fix": "eslint ./src --ext js,ts,tsx,json --fix",
@ -39,7 +39,7 @@
"better-sqlite3": "^8.4.0", "better-sqlite3": "^8.4.0",
"bluebird": "3.7.2", "bluebird": "3.7.2",
"default-gateway": "6.0.3", "default-gateway": "6.0.3",
"dugite": "^2.5.1", "dugite": "2.5.1",
"electron-ipc-cat": "2.0.1", "electron-ipc-cat": "2.0.1",
"electron-settings": "5.0.0", "electron-settings": "5.0.0",
"electron-squirrel-startup": "1.0.0", "electron-squirrel-startup": "1.0.0",

2
pnpm-lock.yaml generated
View file

@ -40,7 +40,7 @@ dependencies:
specifier: 6.0.3 specifier: 6.0.3
version: 6.0.3 version: 6.0.3
dugite: dugite:
specifier: ^2.5.1 specifier: 2.5.1
version: 2.5.1 version: 2.5.1
electron-ipc-cat: electron-ipc-cat:
specifier: 2.0.1 specifier: 2.0.1

View file

@ -7,6 +7,7 @@ const path = require('path');
const glob = require('glob'); const glob = require('glob');
const fs = require('fs-extra'); const fs = require('fs-extra');
const util = require('util'); const util = require('util');
const packageJSON = require('../package.json')
const exec = util.promisify(require('child_process').exec); const exec = util.promisify(require('child_process').exec);
/** /**
@ -38,14 +39,6 @@ exports.default = async (buildPath, electronVersion, platform, arch, callback) =
const tasks = []; const tasks = [];
if (['production', 'test'].includes(process.env.NODE_ENV)) { if (['production', 'test'].includes(process.env.NODE_ENV)) {
console.log('Copying tiddlywiki dependency to dist'); console.log('Copying tiddlywiki dependency to dist');
tasks.push(fs.copy(path.join(projectRoot, 'node_modules', '@tiddlygit', 'tiddlywiki'), path.join(cwd, 'node_modules', '@tiddlygit', 'tiddlywiki'), { dereference: true }));
// it has things like `git/bin/libexec/git-core/git-add` link to `git/bin/libexec/git-core/git`, to reduce size, so can't use `dereference: true` here.
tasks.push(fs.copy(path.join(projectRoot, 'node_modules', '.pnpm', 'dugite@2.5.1', 'node_modules', 'dugite'), path.join(cwd, 'node_modules', 'dugite'), { dereference: false }));
// we only need its `main` binary, no need its dependency and code, because we already copy it to src/services/native/externalApp
tasks.push(fs.mkdirp(path.join(cwd, 'node_modules', 'app-path')).then(async () => {
await fs.copy(path.join(projectRoot, 'node_modules', 'app-path', 'main'), path.join(cwd, 'node_modules', 'app-path', 'main'), { dereference: true })
}));
tasks.push(fs.copy(path.resolve(projectRoot, 'node_modules/better-sqlite3/build/Release/better_sqlite3.node'), path.resolve(cwd, 'node_modules/better-sqlite3/build/Release/better_sqlite3.node'), { dereference: true }));
tasks.push(fs.copy(path.join(projectRoot, 'node_modules', 'zx'), path.join(cwd, 'node_modules', 'zx'), { dereference: true }).then(async () => { tasks.push(fs.copy(path.join(projectRoot, 'node_modules', 'zx'), path.join(cwd, 'node_modules', 'zx'), { dereference: true }).then(async () => {
// not using pnpm, because after using it, it always causing problem here, causing `Error: spawn /bin/sh ENOENT` in github actions // not using pnpm, because after using it, it always causing problem here, causing `Error: spawn /bin/sh ENOENT` in github actions
// it can probably being "working directory didn't exist" in https://github.com/nodejs/node/issues/9644#issuecomment-282060923 // it can probably being "working directory didn't exist" in https://github.com/nodejs/node/issues/9644#issuecomment-282060923
@ -54,11 +47,30 @@ exports.default = async (buildPath, electronVersion, platform, arch, callback) =
await exec(`npm i --legacy-building`, { cwd: path.join(cwd, 'node_modules', 'zx', 'node_modules', 'globby'), shell }); await exec(`npm i --legacy-building`, { cwd: path.join(cwd, 'node_modules', 'zx', 'node_modules', 'globby'), shell });
await exec(`npm i --legacy-building --ignore-scripts`, { cwd: path.join(cwd, 'node_modules', 'zx', 'node_modules', 'node-fetch'), shell }); await exec(`npm i --legacy-building --ignore-scripts`, { cwd: path.join(cwd, 'node_modules', 'zx', 'node_modules', 'node-fetch'), shell });
})); }));
const packagePathsToCopyDereferenced = [
['@tiddlygit', 'tiddlywiki'],
['llama-node'],
['@llama-node','llama-cpp'],
['@llama-node','core'],
['@llama-node','rwkv-cpp'],
['better-sqlite3','build','Release','better_sqlite3.node'],
]
for (const packagePathInNodeModules of packagePathsToCopyDereferenced) {
// some binary may not exist in other platforms, so allow failing here.
tasks.push(fs.copy(path.resolve(projectRoot, 'node_modules', ...packagePathInNodeModules), path.resolve(cwd, 'node_modules', ...packagePathInNodeModules), { dereference: true }));
}
const sqliteVssPackages = ['sqlite-vss-linux-x64', 'sqlite-vss-darwin-x64', 'sqlite-vss-darwin-arm64'] const sqliteVssPackages = ['sqlite-vss-linux-x64', 'sqlite-vss-darwin-x64', 'sqlite-vss-darwin-arm64']
for (const sqliteVssPackage of sqliteVssPackages) { for (const sqliteVssPackage of sqliteVssPackages) {
// some binary may not exist in other platforms, so allow failing here. // some binary may not exist in other platforms, so allow failing here.
tasks.push(fs.copy(path.resolve(projectRoot, `node_modules/${sqliteVssPackage}`), path.resolve(cwd, `node_modules/${sqliteVssPackage}`), { dereference: true }).catch(() => {})); tasks.push(fs.copy(path.resolve(projectRoot, 'node_modules', sqliteVssPackage), path.resolve(cwd, 'node_modules', sqliteVssPackage), { dereference: true }).catch(() => {}));
} }
// it has things like `git/bin/libexec/git-core/git-add` link to `git/bin/libexec/git-core/git`, to reduce size, so can't use `dereference: true` here.
// And pnpm will have node_modules/dugite to be a shortcut, can't just copy it with `dereference: false`, have to copy from .pnpm folder
tasks.push(fs.copy(path.join(projectRoot, 'node_modules', '.pnpm', `dugite@${packageJSON.dependencies.dugite}`, 'node_modules', 'dugite'), path.join(cwd, 'node_modules', 'dugite'), { dereference: false }));
// we only need its `main` binary, no need its dependency and code, because we already copy it to src/services/native/externalApp
tasks.push(fs.mkdirp(path.join(cwd, 'node_modules', 'app-path')).then(async () => {
await fs.copy(path.join(projectRoot, 'node_modules', 'app-path', 'main'), path.join(cwd, 'node_modules', 'app-path', 'main'), { dereference: true })
}));
} }
/** sign it for mac m1 https://www.zhihu.com/question/431722091/answer/1592339574 (only work if user run this.) /** sign it for mac m1 https://www.zhihu.com/question/431722091/answer/1592339574 (only work if user run this.)
* And have error * And have error

View file

@ -143,8 +143,11 @@ export interface IWorkflowListItem {
graphJSONString: string; graphJSONString: string;
id: string; id: string;
image?: string; image?: string;
/**
* Things that only exist on runtime, and won't be persisted.
*/
metadata?: { metadata?: {
tiddler: IWorkflowTiddler; tiddler?: IWorkflowTiddler;
workspace?: IWorkspaceWithMetadata; workspace?: IWorkspaceWithMetadata;
}; };
tags: string[]; tags: string[];

View file

@ -5,10 +5,10 @@ import React, { ChangeEvent, useCallback, useState } from 'react';
import SimpleBar from 'simplebar-react'; import SimpleBar from 'simplebar-react';
import styled from 'styled-components'; import styled from 'styled-components';
import { useTranslation } from 'react-i18next';
import { AddItemDialog } from './AddItemDialog'; import { AddItemDialog } from './AddItemDialog';
import { useAvailableFilterTags, useWorkflows } from './useWorkflowDataSource'; import { useAvailableFilterTags, useWorkflows } from './useWorkflowDataSource';
import { IWorkflowListItem, WorkflowList } from './WorkflowList'; import { IWorkflowListItem, WorkflowList } from './WorkflowList';
import { useTranslation } from 'react-i18next';
const WorkflowManageContainer = styled(Box)` const WorkflowManageContainer = styled(Box)`
display: flex; display: flex;

View file

@ -1,10 +1,17 @@
import { dialog, net } from 'electron'; import { dialog, net } from 'electron';
import { getRemoteName, getRemoteUrl, GitStep, ModifiedFileList } from 'git-sync-js'; import { getRemoteName, getRemoteUrl, GitStep, ModifiedFileList } from 'git-sync-js';
import { inject, injectable } from 'inversify'; import { inject, injectable } from 'inversify';
import { Observer } from 'rxjs';
import { ModuleThread, spawn, Worker } from 'threads'; import { ModuleThread, spawn, Worker } from 'threads';
// @ts-expect-error it don't want .ts
// eslint-disable-next-line import/no-webpack-loader-syntax
import workerURL from 'threads-plugin/dist/loader?name=gitWorker!./gitWorker.ts';
import { LOCAL_GIT_DIRECTORY } from '@/constants/appPaths';
import { WikiChannel } from '@/constants/channels'; import { WikiChannel } from '@/constants/channels';
import type { IAuthenticationService, ServiceBranchTypes } from '@services/auth/interface'; import type { IAuthenticationService, ServiceBranchTypes } from '@services/auth/interface';
import { lazyInject } from '@services/container';
import { i18n } from '@services/libs/i18n'; import { i18n } from '@services/libs/i18n';
import { logger } from '@services/libs/log'; import { logger } from '@services/libs/log';
import type { INativeService } from '@services/native/interface'; import type { INativeService } from '@services/native/interface';
@ -13,17 +20,10 @@ import serviceIdentifier from '@services/serviceIdentifier';
import type { IViewService } from '@services/view/interface'; import type { IViewService } from '@services/view/interface';
import type { IWikiService } from '@services/wiki/interface'; import type { IWikiService } from '@services/wiki/interface';
import type { IWindowService } from '@services/windows/interface'; import type { IWindowService } from '@services/windows/interface';
import { Observer } from 'rxjs';
import { GitWorker } from './gitWorker';
import { ICommitAndSyncConfigs, IGitLogMessage, IGitService, IGitUserInfos } from './interface';
import { LOCAL_GIT_DIRECTORY } from '@/constants/appPaths';
import { lazyInject } from '@services/container';
import { WindowNames } from '@services/windows/WindowProperties'; import { WindowNames } from '@services/windows/WindowProperties';
import { IWorkspace } from '@services/workspaces/interface'; import { IWorkspace } from '@services/workspaces/interface';
// @ts-expect-error it don't want .ts import { GitWorker } from './gitWorker';
// eslint-disable-next-line import/no-webpack-loader-syntax import { ICommitAndSyncConfigs, IGitLogMessage, IGitService, IGitUserInfos } from './interface';
import workerURL from 'threads-plugin/dist/loader?name=gitWorker!./gitWorker.ts';
import { stepWithChanges } from './stepWithChanges'; import { stepWithChanges } from './stepWithChanges';
@injectable() @injectable()
@ -51,8 +51,9 @@ export class Git implements IGitService {
private async initWorker(): Promise<void> { private async initWorker(): Promise<void> {
process.env.LOCAL_GIT_DIRECTORY = LOCAL_GIT_DIRECTORY; process.env.LOCAL_GIT_DIRECTORY = LOCAL_GIT_DIRECTORY;
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument logger.debug(`initial gitWorker with ${workerURL as string}`, { function: 'Git.initWorker', LOCAL_GIT_DIRECTORY });
this.gitWorker = await spawn<GitWorker>(new Worker(workerURL), { timeout: 1000 * 60 }); this.gitWorker = await spawn<GitWorker>(new Worker(workerURL as string), { timeout: 1000 * 60 });
logger.debug(`initial gitWorker done`, { function: 'Git.initWorker' });
} }
public async getModifiedFileList(wikiFolderPath: string): Promise<ModifiedFileList[]> { public async getModifiedFileList(wikiFolderPath: string): Promise<ModifiedFileList[]> {

View file

@ -36,8 +36,21 @@ export class LanguageModel implements ILanguageModelService {
private llmWorker?: ModuleThread<LLMWorker>; private llmWorker?: ModuleThread<LLMWorker>;
private async initWorker(): Promise<void> { private async initWorker(): Promise<void> {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument logger.debug(`initial llmWorker with ${workerURL as string}`, { function: 'LanguageModel.initWorker' });
this.llmWorker = await spawn<LLMWorker>(new Worker(workerURL), { timeout: 1000 * 60 }); try {
this.llmWorker = await spawn<LLMWorker>(new Worker(workerURL as string), { timeout: 1000 * 30 });
logger.debug(`initial llmWorker done`, { function: 'LanguageModel.initWorker' });
} catch (error) {
if ((error as Error).message.includes('Did not receive an init message from worker after')) {
// https://github.com/andywer/threads.js/issues/426
// wait some time and restart the wiki will solve this
logger.warn(`initWorker() handle "${(error as Error)?.message}", will try recreate worker.`, { function: 'LanguageModel.initWorker' });
await this.initWorker();
} else {
logger.warn('initWorker() unexpected error, throw it', { function: 'LanguageModel.initWorker' });
throw error;
}
}
} }
/** /**
@ -99,18 +112,13 @@ export class LanguageModel implements ILanguageModelService {
return new Observable<ILLMResultPart>((subscriber) => { return new Observable<ILLMResultPart>((subscriber) => {
const getWikiChangeObserverIIFE = async () => { const getWikiChangeObserverIIFE = async () => {
const worker = await this.getWorker(); const worker = await this.getWorker();
// const template = `Write a short helloworld in JavaScript.`;
// const prompt = `A chat between a user and a useful assistant.
// USER: ${template}
// ASSISTANT:`;
const { defaultModel } = await this.preferenceService.get('languageModel'); const { defaultModel } = await this.preferenceService.get('languageModel');
const modelPath = path.join(LANGUAGE_MODEL_FOLDER, modelName ?? defaultModel['llama.cpp']); const modelPath = path.join(LANGUAGE_MODEL_FOLDER, modelName ?? defaultModel['llama.cpp']);
if (!(await this.checkModelExistsAndWarnUser(modelPath))) { if (!(await this.checkModelExistsAndWarnUser(modelPath))) {
subscriber.error(new Error(`${i18n.t('LanguageModel.ModelNotExist')} ${modelPath}`)); subscriber.error(new Error(`${i18n.t('LanguageModel.ModelNotExist')} ${modelPath}`));
return; return;
} }
const observable = worker.runLLama$({ prompt, modelPath, conversationID }); const observable = worker.runLLama({ prompt, modelPath, conversationID, openDebugger: false });
observable.subscribe({ observable.subscribe({
next: (result) => { next: (result) => {
const loggerCommonMeta = { id: result.id, function: 'LanguageModel.runLLama$' }; const loggerCommonMeta = { id: result.id, function: 'LanguageModel.runLLama$' };

View file

@ -55,7 +55,7 @@ export interface IRunLLAmaOptions extends ILLMResultBase {
/** /**
* Test language model on renderer by: * Test language model on renderer by:
* ```js * ```js
* window.observables.languageModel.runLLama$({ id: '1' }).subscribe({ next: console.log, error: console.error, complete: () => console.warn('completed') }) * window.observables.languageModel.runLLama$({ prompt: 'A chat between a user and an assistant.\nUSER: You are a helpful assistant. Write a simple hello world in JS.\nASSISTANT:\n', id: '1' }).subscribe({ next: console.log, error: console.error, complete: () => console.warn('completed') })
* ``` * ```
*/ */

View file

@ -1,21 +1,30 @@
/* eslint-disable @typescript-eslint/no-misused-promises */ /* eslint-disable @typescript-eslint/no-misused-promises */
import 'source-map-support/register'; import 'source-map-support/register';
import { LLM } from 'llama-node'; import type { LoadConfig as LLamaLoadConfig } from 'llama-node/dist/llm/llama-cpp';
import { LLamaCpp, LoadConfig as LLamaLoadConfig } from 'llama-node/dist/llm/llama-cpp.js'; import inspector from 'node:inspector';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { expose } from 'threads/worker'; import { expose } from 'threads/worker';
import { ILanguageModelWorkerResponse } from './interface'; import { ILanguageModelWorkerResponse } from './interface';
const DEFAULT_TIMEOUT_DURATION = 1000 * 30; const DEFAULT_TIMEOUT_DURATION = 1000 * 30;
function runLLama$( function runLLama(
options: { conversationID: string; modelPath: string; prompt: string }, options: { conversationID: string; modelPath: string; openDebugger?: boolean; prompt: string },
): Observable<ILanguageModelWorkerResponse> { ): Observable<ILanguageModelWorkerResponse> {
const { conversationID, modelPath, prompt } = options; const { conversationID, modelPath, prompt, openDebugger } = options;
const loggerCommonMeta = { level: 'info' as const, meta: { function: 'llmWorker.runLLama$' }, id: conversationID }; if (openDebugger === true) {
inspector.open();
inspector.waitForDebugger();
// eslint-disable-next-line no-debugger
debugger;
}
const loggerCommonMeta = { level: 'info' as const, meta: { function: 'llmWorker.runLLama' }, id: conversationID };
return new Observable<ILanguageModelWorkerResponse>((subscriber) => { return new Observable<ILanguageModelWorkerResponse>((subscriber) => {
void (async function runLLamaObservableIIFE() { void (async function runLLamaObservableIIFE() {
try { try {
subscriber.next({ message: 'preparing instance and config', ...loggerCommonMeta }); subscriber.next({ message: 'preparing instance and config', ...loggerCommonMeta });
const { LLM } = await import('llama-node');
// use dynamic import cjs version to fix https://github.com/andywer/threads.js/issues/478
const { LLamaCpp } = await import('llama-node/dist/llm/llama-cpp.cjs');
const llama = new LLM(LLamaCpp); const llama = new LLM(LLamaCpp);
const config: LLamaLoadConfig = { const config: LLamaLoadConfig = {
modelPath, modelPath,
@ -76,6 +85,6 @@ function runLLama$(
}); });
} }
const llmWorker = { runLLama$ }; const llmWorker = { runLLama };
export type LLMWorker = typeof llmWorker; export type LLMWorker = typeof llmWorker;
expose(llmWorker); expose(llmWorker);

View file

@ -20,7 +20,7 @@ export const defaultPreferences: IPreferences = {
'llama.cpp': 'llama.bin', 'llama.cpp': 'llama.bin',
'rwkv.cpp': 'rwkv.bin', 'rwkv.cpp': 'rwkv.bin',
}, },
timeoutDuration: 1000 * 30, timeoutDuration: 1000 * 60,
}, },
menuBarAlwaysOnTop: false, menuBarAlwaysOnTop: false,
pauseNotifications: '', pauseNotifications: '',

View file

@ -32,15 +32,16 @@ import { getSubWikiPluginContent, ISubWikiPluginContent, updateSubWikiPluginCont
import type { IStartNodeJSWikiConfigs, WikiWorker } from './wikiWorker'; import type { IStartNodeJSWikiConfigs, WikiWorker } from './wikiWorker';
import type { IpcServerRouteMethods, IpcServerRouteNames } from './wikiWorker/ipcServerRoutes'; import type { IpcServerRouteMethods, IpcServerRouteNames } from './wikiWorker/ipcServerRoutes';
// @ts-expect-error it don't want .ts
// eslint-disable-next-line import/no-webpack-loader-syntax
import workerURL from 'threads-plugin/dist/loader?name=wikiWorker!./wikiWorker/index.ts';
import { LOG_FOLDER } from '@/constants/appPaths'; import { LOG_FOLDER } from '@/constants/appPaths';
import { isDevelopmentOrTest } from '@/constants/environment'; import { isDevelopmentOrTest } from '@/constants/environment';
import { defaultServerIP } from '@/constants/urls'; import { defaultServerIP } from '@/constants/urls';
import { IDatabaseService } from '@services/database/interface'; import { IDatabaseService } from '@services/database/interface';
import { IPreferenceService } from '@services/preferences/interface'; import { IPreferenceService } from '@services/preferences/interface';
import { mapValues } from 'lodash'; import { mapValues } from 'lodash';
// @ts-expect-error it don't want .ts
// eslint-disable-next-line import/no-webpack-loader-syntax
import workerURL from 'threads-plugin/dist/loader?name=wikiWorker!./wikiWorker/index.ts';
import { wikiWorkerStartedEventName } from './constants'; import { wikiWorkerStartedEventName } from './constants';
import { IWikiOperations, wikiOperations } from './wikiOperations'; import { IWikiOperations, wikiOperations } from './wikiOperations';
@ -143,7 +144,9 @@ export class Wiki implements IWikiService {
tokenAuth, tokenAuth,
userName, userName,
}; };
logger.debug(`initial wikiWorker with ${workerURL as string} for workspaceID ${workspaceID}`, { function: 'Wiki.startWiki' });
const worker = await spawn<WikiWorker>(new Worker(workerURL as string), { timeout: 1000 * 60 }); const worker = await spawn<WikiWorker>(new Worker(workerURL as string), { timeout: 1000 * 60 });
logger.debug(`initial wikiWorker done`, { function: 'Wiki.startWiki' });
this.wikiWorkers[workspaceID] = worker; this.wikiWorkers[workspaceID] = worker;
this.wikiWorkerStartedEventTarget.dispatchEvent(new Event(wikiWorkerStartedEventName(workspaceID))); this.wikiWorkerStartedEventTarget.dispatchEvent(new Event(wikiWorkerStartedEventName(workspaceID)));
const wikiLogger = startWikiLogger(workspaceID, name); const wikiLogger = startWikiLogger(workspaceID, name);

4
src/type.d.ts vendored
View file

@ -9,6 +9,10 @@ declare module '@tiddlygit/tiddlywiki' {
export * from 'tiddlywiki'; export * from 'tiddlywiki';
} }
declare module 'llama-node/dist/llm/llama-cpp.cjs' {
export { LLamaCpp } from 'llama-node/dist/llm/llama-cpp';
}
declare module 'the-graph' { declare module 'the-graph' {
import { Graph, GraphEdge, GraphNode } from 'fbp-graph'; import { Graph, GraphEdge, GraphNode } from 'fbp-graph';
import { MutableRefObject } from 'react'; import { MutableRefObject } from 'react';

View file

@ -48,11 +48,18 @@ module.exports = {
}, },
}, },
externals: [ externals: [
// TODO: simply external things will make require can't find things. May need some other way. // simply external all things will make require can't find things. Only exclude what we copied in scripts/afterPack.js
// nodeExternals({ // nodeExternals({
// additionalModuleDirs: ['@tiddlygit/tiddlywiki'], // additionalModuleDirs: ['@tiddlygit/tiddlywiki'],
// allowlist: [/(threads-plugin)/], // allowlist: [/(threads-plugin)/],
// }), // }),
'@tiddlygit/tiddlywiki',
'llama-node',
'@llama-node/llama-cpp',
'@llama-node/core',
'@llama-node/rwkv-cpp',
'dugite',
'zx',
], ],
// externalsType: 'commonjs', // externalsType: 'commonjs',
// externalsPresets: { electronMain: true }, // externalsPresets: { electronMain: true },

View file

@ -41,7 +41,8 @@ exports.main = _.compact([
}), }),
new ExternalsPlugin({ new ExternalsPlugin({
type: 'commonjs', type: 'commonjs',
include: /@tiddlygit\+tiddlywiki@(.+)/, // use regex works.
include: /@tiddlygit\+tiddlywiki@(.+)|llama-node(.+)|@llama-node(.+)/,
// when using npm, we can use this. But with pnpm, this won't work ↓ // when using npm, we can use this. But with pnpm, this won't work ↓
// include: path.join(__dirname, 'node_modules', '.pnpm', '@tiddlygit', 'tiddlywiki'), // include: path.join(__dirname, 'node_modules', '.pnpm', '@tiddlygit', 'tiddlywiki'),
}), }),