Merge branch 'main' into fix315
This commit is contained in:
commit
8d004ff0ed
3
.github/workflows/linter-and-test.yml
vendored
3
.github/workflows/linter-and-test.yml
vendored
@ -32,6 +32,7 @@ jobs:
|
|||||||
rm -rf ./* || true
|
rm -rf ./* || true
|
||||||
rm -rf ./.??* || true
|
rm -rf ./.??* || true
|
||||||
ls -la ./
|
ls -la ./
|
||||||
|
rm -rf ~/Library/Application\ Support/jan
|
||||||
- name: Getting the repo
|
- name: Getting the repo
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
@ -58,6 +59,7 @@ jobs:
|
|||||||
- name: Clean workspace
|
- name: Clean workspace
|
||||||
run: |
|
run: |
|
||||||
Remove-Item -Path .\* -Force -Recurse
|
Remove-Item -Path .\* -Force -Recurse
|
||||||
|
Remove-Item -Path "$Env:APPDATA\jan" -Force -Recurse
|
||||||
- name: Getting the repo
|
- name: Getting the repo
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
@ -85,6 +87,7 @@ jobs:
|
|||||||
rm -rf ./* || true
|
rm -rf ./* || true
|
||||||
rm -rf ./.??* || true
|
rm -rf ./.??* || true
|
||||||
ls -la ./
|
ls -la ./
|
||||||
|
rm -rf ~/.config/jan
|
||||||
- name: Getting the repo
|
- name: Getting the repo
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
|||||||
91
.github/workflows/publish-plugins.yml
vendored
Normal file
91
.github/workflows/publish-plugins.yml
vendored
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
name: Publish plugins/$dir Package to npmjs
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths:
|
||||||
|
- "plugins/**"
|
||||||
|
- ".github/workflows/publish-plugins.yml"
|
||||||
|
- "!plugins/*/package.json"
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
environment: production
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: "0"
|
||||||
|
token: ${{ secrets.PAT_SERVICE_ACCOUNT }}
|
||||||
|
|
||||||
|
- name: Install jq
|
||||||
|
uses: dcarbone/install-jq-action@v2.0.1
|
||||||
|
|
||||||
|
- name: Check Path Change
|
||||||
|
run: |
|
||||||
|
git config --global user.email "service@jan.ai"
|
||||||
|
git config --global user.name "Service Account"
|
||||||
|
echo "Changes in these directories trigger the build:"
|
||||||
|
changed_dirs=$(git -c http.extraheader="AUTHORIZATION: bearer ${{ secrets.GITHUB_TOKEN }}" diff --name-only HEAD HEAD~1 | grep '^plugins/' | awk -F/ '{print $2}' | uniq)
|
||||||
|
echo $changed_dirs > /tmp/change_dir.txt
|
||||||
|
|
||||||
|
- name: "Auto Increase package Version"
|
||||||
|
run: |
|
||||||
|
cd plugins
|
||||||
|
for dir in $(cat /tmp/change_dir.txt)
|
||||||
|
do
|
||||||
|
echo "$dir"
|
||||||
|
# Extract current version
|
||||||
|
current_version=$(jq -r '.version' $dir/package.json)
|
||||||
|
|
||||||
|
# Break the version into its components
|
||||||
|
major_version=$(echo $current_version | cut -d "." -f 1)
|
||||||
|
minor_version=$(echo $current_version | cut -d "." -f 2)
|
||||||
|
patch_version=$(echo $current_version | cut -d "." -f 3)
|
||||||
|
|
||||||
|
# Increment the patch version by one
|
||||||
|
new_patch_version=$((patch_version+1))
|
||||||
|
|
||||||
|
# Construct the new version
|
||||||
|
new_version="$major_version.$minor_version.$new_patch_version"
|
||||||
|
|
||||||
|
# Replace the old version with the new version in package.json
|
||||||
|
jq --arg version "$new_version" '.version = $version' $dir/package.json > /tmp/package.json && mv /tmp/package.json $dir/package.json
|
||||||
|
|
||||||
|
# Print the new version
|
||||||
|
echo "Updated $dir package.json version to: $new_version"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Setup .npmrc file to publish to npm
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: "20.x"
|
||||||
|
registry-url: "https://registry.npmjs.org"
|
||||||
|
|
||||||
|
- name: Publish npm packages
|
||||||
|
run: |
|
||||||
|
cd plugins
|
||||||
|
for dir in $(cat /tmp/change_dir.txt)
|
||||||
|
do
|
||||||
|
echo $dir
|
||||||
|
cd $dir
|
||||||
|
npm install && npm run build
|
||||||
|
npm publish --access public
|
||||||
|
cd ..
|
||||||
|
done
|
||||||
|
env:
|
||||||
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||||
|
|
||||||
|
- name: "Commit new version to main and create tag"
|
||||||
|
run: |
|
||||||
|
for dir in $(cat /tmp/change_dir.txt)
|
||||||
|
do
|
||||||
|
echo "$dir"
|
||||||
|
version=$(jq -r '.version' plugins/$dir/package.json)
|
||||||
|
git config --global user.email "service@jan.ai"
|
||||||
|
git config --global user.name "Service Account"
|
||||||
|
git add plugins/$dir/package.json
|
||||||
|
git commit -m "${GITHUB_REPOSITORY}: Update tag build $version for $dir"
|
||||||
|
git -c http.extraheader="AUTHORIZATION: bearer ${{ secrets.PAT_SERVICE_ACCOUNT }}" push origin HEAD:main
|
||||||
|
git tag -a $dir-$version -m "${GITHUB_REPOSITORY}: Update tag build $version for $dir"
|
||||||
|
git -c http.extraheader="AUTHORIZATION: bearer ${{ secrets.PAT_SERVICE_ACCOUNT }}" push origin $dir-$version
|
||||||
|
done
|
||||||
54
adr/adr-001-jan-deployable-cloud-native.md
Normal file
54
adr/adr-001-jan-deployable-cloud-native.md
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
# ADR #001: Jan deployable cloud-native
|
||||||
|
|
||||||
|
## Changelog
|
||||||
|
|
||||||
|
- 23.10.03: Initial unfinished draft
|
||||||
|
- 23.10.16: Remove authentication
|
||||||
|
|
||||||
|
## Authors
|
||||||
|
|
||||||
|
- @nam-john-ho
|
||||||
|
- @louis
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
### Status Quo
|
||||||
|
|
||||||
|
* User doesn't have a local GPU machine but wants to run Jan on a rented server
|
||||||
|
* User wants a quick, fast way to experiment with Jan on a rented GPU
|
||||||
|
* https://github.com/janhq/jan/issues/255
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
* This ADR aims to outline design decisions for deploying Jan in cloud native environments such as: Runpod, AWS, Azure, GCP in a fast and simple way.
|
||||||
|
* The current code-base should not change too much.
|
||||||
|
* The current plugins must be reusable across enviroments (Desktop, Cloud-native).
|
||||||
|
|
||||||
|
|
||||||
|
### Key Design Decisions
|
||||||
|

|
||||||
|
#### Why middleware
|
||||||
|
* The /web codebase needs to operate in both browser and electron environments
|
||||||
|
* The /web codebase needs to route plugin routes accordingly, either to /server or /electron
|
||||||
|
* Middleware takes care of this
|
||||||
|
* We will have a /server codebase that takes care of routing to plugins
|
||||||
|
#### Unsuitable Alternatives
|
||||||
|
* Not possible to just run electron headless
|
||||||
|
* /web is on a different chromium window
|
||||||
|
* Does not have all the electron handlers
|
||||||
|
* Does not have the IPC handler
|
||||||
|
|
||||||
|
## Alternative Approaches
|
||||||
|
Separated server process runs along side with electron. https://github.com/janhq/jan/pull/184/commits/6005409a945bb0e80a61132b9eb77f47f19d0aa6
|
||||||
|
|
||||||
|
## Considerations
|
||||||
|
* Due to the limitation of accessing the file system in web browsers, the first version of the web app will load all the current plugins by default, and users will not be able to add, remove, or update plugins.
|
||||||
|
* Simple authentication will be implemented as a plugin.
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- https://www.runpod.io/console/templates
|
||||||
|
- https://repost.aws/articles/ARQ0Tz9eorSL6EAus7XPMG-Q/how-to-install-textgen-webui-on-aws
|
||||||
|
- https://www.youtube.com/watch?v=_59AsSyMERQ
|
||||||
|
- https://gpus.llm-utils.org/running-llama-2-on-runpod-with-oobaboogas-text-generation-webui/
|
||||||
|
- https://medium.com/@jarimh1984/installing-oobabooga-and-oobabooga-api-to-runpod-cloud-step-by-step-tutorial-47457974dfa5
|
||||||
@ -3,6 +3,9 @@
|
|||||||
## Changelog
|
## Changelog
|
||||||
- {date}: {changelog}
|
- {date}: {changelog}
|
||||||
|
|
||||||
|
## Authors
|
||||||
|
- @usernames
|
||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
What is the status, such as proposed, accepted, rejected, deprecated, superseded, etc.?
|
What is the status, such as proposed, accepted, rejected, deprecated, superseded, etc.?
|
||||||
@ -21,4 +24,6 @@ What is the change that we're proposing and/or doing?
|
|||||||
|
|
||||||
What becomes easier or more difficult to do because of this change?
|
What becomes easier or more difficult to do because of this change?
|
||||||
|
|
||||||
|
## Alternatives
|
||||||
|
|
||||||
## Reference
|
## Reference
|
||||||
BIN
adr/images/adr-001-01.png
Normal file
BIN
adr/images/adr-001-01.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 172 KiB |
BIN
adr/images/adr-001-02.png
Normal file
BIN
adr/images/adr-001-02.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 270 KiB |
@ -240,7 +240,6 @@ const config = {
|
|||||||
additionalLanguages: ["python"],
|
additionalLanguages: ["python"],
|
||||||
},
|
},
|
||||||
colorMode: {
|
colorMode: {
|
||||||
defaultMode: "dark",
|
|
||||||
disableSwitch: false,
|
disableSwitch: false,
|
||||||
respectPrefersColorScheme: false,
|
respectPrefersColorScheme: false,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -47,13 +47,7 @@ export default function HomepageHero() {
|
|||||||
Run your own AI
|
Run your own AI
|
||||||
</h1>
|
</h1>
|
||||||
<p className="mt-6 text-lg leading-8 text-gray-600 dark:text-gray-300">
|
<p className="mt-6 text-lg leading-8 text-gray-600 dark:text-gray-300">
|
||||||
Jan lets you run AI on your own hardware. 1-click to install the
|
Run Large Language Models locally on Mac, Windows or Linux.
|
||||||
latest open-source models. Monitor and manage software-hardware
|
|
||||||
performance.
|
|
||||||
<br></br>
|
|
||||||
Jan is
|
|
||||||
<strong> free and open core</strong> with a Sustainable Use
|
|
||||||
License.
|
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-10 flex items-center justify-center gap-x-6">
|
<div className="mt-10 flex items-center justify-center gap-x-6">
|
||||||
{/* TODO: handle mobile model download app instead */}
|
{/* TODO: handle mobile model download app instead */}
|
||||||
@ -78,8 +72,7 @@ export default function HomepageHero() {
|
|||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
colorMode === "dark"
|
colorMode === "dark"
|
||||||
? // TODO replace with darkmode image
|
? require("@site/static/img/desktop-llm-chat-dark.png")
|
||||||
require("@site/static/img/desktop-llm-chat-dark.png")
|
|
||||||
.default
|
.default
|
||||||
: require("@site/static/img/desktop-llm-chat-light.png")
|
: require("@site/static/img/desktop-llm-chat-light.png")
|
||||||
.default
|
.default
|
||||||
|
|||||||
@ -19,7 +19,7 @@ export default function Home() {
|
|||||||
title={`${siteConfig.tagline}`}
|
title={`${siteConfig.tagline}`}
|
||||||
description="Description will go into a meta tag in <head />"
|
description="Description will go into a meta tag in <head />"
|
||||||
>
|
>
|
||||||
<HomepageBanner />
|
{/* <HomepageBanner /> */}
|
||||||
<main className={styles.main}>
|
<main className={styles.main}>
|
||||||
<HomepageHero />
|
<HomepageHero />
|
||||||
<HomepageSectionOne />
|
<HomepageSectionOne />
|
||||||
|
|||||||
560
docs/yarn.lock
560
docs/yarn.lock
File diff suppressed because it is too large
Load Diff
@ -1,23 +0,0 @@
|
|||||||
const MODULE_PATH = "inference-plugin/dist/module.js";
|
|
||||||
|
|
||||||
const initModel = async (product) =>
|
|
||||||
new Promise(async (resolve) => {
|
|
||||||
if (window.electronAPI) {
|
|
||||||
window.electronAPI
|
|
||||||
.invokePluginFunc(MODULE_PATH, "initModel", product)
|
|
||||||
.then((res) => resolve(res));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const inferenceUrl = () => "http://localhost:3928/llama/chat_completion";
|
|
||||||
|
|
||||||
const stopModel = () => {
|
|
||||||
window.electronAPI.invokePluginFunc(MODULE_PATH, "killSubprocess");
|
|
||||||
};
|
|
||||||
|
|
||||||
// Register all the above functions and objects with the relevant extension points
|
|
||||||
export function init({ register }) {
|
|
||||||
register("initModel", "initModel", initModel);
|
|
||||||
register("inferenceUrl", "inferenceUrl", inferenceUrl);
|
|
||||||
register("stopModel", "stopModel", stopModel);
|
|
||||||
}
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
/* Visit https://aka.ms/tsconfig to read more about this file */
|
|
||||||
/* Language and Environment */
|
|
||||||
"target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
|
|
||||||
/* Modules */
|
|
||||||
"module": "ES6" /* Specify what module code is generated. */,
|
|
||||||
// "rootDir": "./", /* Specify the root folder within your source files. */
|
|
||||||
// "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
|
|
||||||
// "baseUrl": "." /* Specify the base directory to resolve non-relative module names. */,
|
|
||||||
// "paths": {} /* Specify a set of entries that re-map imports to additional lookup locations. */,
|
|
||||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
|
||||||
// "resolveJsonModule": true, /* Enable importing .json files. */
|
|
||||||
|
|
||||||
"outDir": "./dist" /* Specify an output folder for all emitted files. */,
|
|
||||||
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
|
|
||||||
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
|
|
||||||
/* Type Checking */
|
|
||||||
"strict": false /* Enable all strict type-checking options. */,
|
|
||||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
export {};
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface Window {
|
|
||||||
electronAPI?: any | undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -22,8 +22,8 @@
|
|||||||
"build:core": "cd plugin-core && yarn install && yarn run build",
|
"build:core": "cd plugin-core && yarn install && yarn run build",
|
||||||
"build:web": "yarn workspace jan-web build && cpx \"web/out/**\" \"electron/renderer/\"",
|
"build:web": "yarn workspace jan-web build && cpx \"web/out/**\" \"electron/renderer/\"",
|
||||||
"build:electron": "yarn workspace jan build",
|
"build:electron": "yarn workspace jan build",
|
||||||
"build:plugins": "rimraf ./electron/core/pre-install/*.tgz && concurrently \"cd ./electron/core/plugins/data-plugin && npm ci\" \"cd ./electron/core/plugins/inference-plugin && npm ci\" \"cd ./electron/core/plugins/model-management-plugin && npm ci\" \"cd ./electron/core/plugins/monitoring-plugin && npm ci\" && concurrently \"cd ./electron/core/plugins/data-plugin && npm run build:publish\" \"cd ./electron/core/plugins/inference-plugin && npm run build:publish\" \"cd ./electron/core/plugins/model-management-plugin && npm run build:publish\" \"cd ./electron/core/plugins/monitoring-plugin && npm run build:publish\"",
|
"build:plugins": "rimraf ./electron/core/pre-install/*.tgz && concurrently --kill-others-on-fail \"cd ./plugins/data-plugin && npm install && npm run postinstall\" \"cd ./plugins/inference-plugin && npm install && npm run postinstall\" \"cd ./plugins/model-management-plugin && npm install && npm run postinstall\" \"cd ./plugins/monitoring-plugin && npm install && npm run postinstall\" && concurrently --kill-others-on-fail \"cd ./plugins/data-plugin && npm run build:publish\" \"cd ./plugins/inference-plugin && npm run build:publish\" \"cd ./plugins/model-management-plugin && npm run build:publish\" \"cd ./plugins/monitoring-plugin && npm run build:publish\"",
|
||||||
"build:plugins-darwin": "rimraf ./electron/core/pre-install/*.tgz && concurrently \"cd ./electron/core/plugins/data-plugin && npm ci\" \"cd ./electron/core/plugins/inference-plugin && npm ci\" \"cd ./electron/core/plugins/model-management-plugin && npm ci\" \"cd ./electron/core/plugins/monitoring-plugin && npm ci\" && chmod +x ./electron/auto-sign.sh && ./electron/auto-sign.sh && concurrently \"cd ./electron/core/plugins/data-plugin && npm run build:publish\" \"cd ./electron/core/plugins/inference-plugin && npm run build:publish\" \"cd ./electron/core/plugins/model-management-plugin && npm run build:publish\" \"cd ./electron/core/plugins/monitoring-plugin && npm run build:publish\"",
|
"build:plugins-darwin": "rimraf ./electron/core/pre-install/*.tgz && concurrently \"cd ./plugins/data-plugin && npm install && npm run postinstall\" \"cd ./plugins/inference-plugin && npm install && npm run postinstall\" \"cd ./plugins/model-management-plugin && npm install && npm run postinstall\" \"cd ./plugins/monitoring-plugin && npm install && npm run postinstall\" && chmod +x ./electron/auto-sign.sh && ./electron/auto-sign.sh && concurrently \"cd ./plugins/data-plugin && npm run build:publish\" \"cd ./plugins/inference-plugin && npm run build:publish\" \"cd ./plugins/model-management-plugin && npm run build:publish\" \"cd ./plugins/monitoring-plugin && npm run build:publish\"",
|
||||||
"build": "yarn build:web && yarn build:electron",
|
"build": "yarn build:web && yarn build:electron",
|
||||||
"build:darwin": "yarn build:web && yarn workspace jan build:darwin",
|
"build:darwin": "yarn build:web && yarn workspace jan build:darwin",
|
||||||
"build:win32": "yarn build:web && yarn workspace jan build:win32",
|
"build:win32": "yarn build:web && yarn workspace jan build:win32",
|
||||||
|
|||||||
@ -34,20 +34,7 @@ export function init({ register }: { register: RegisterExtensionPoint }) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Access Core API
|
### Interact with Local Data Storage
|
||||||
|
|
||||||
To access the Core API in your plugin, you can follow the code examples and explanations provided below.
|
|
||||||
|
|
||||||
##### Import Core API and Store Module
|
|
||||||
|
|
||||||
In your main entry code (e.g., `index.ts`), start by importing the necessary modules and functions from the `@janhq/plugin-core` library.
|
|
||||||
|
|
||||||
```js
|
|
||||||
// index.ts
|
|
||||||
import { store, core } from "@janhq/plugin-core";
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Interact with Local Data Storage
|
|
||||||
|
|
||||||
The Core API allows you to interact with local data storage. Here are a couple of examples of how you can use it:
|
The Core API allows you to interact with local data storage. Here are a couple of examples of how you can use it:
|
||||||
|
|
||||||
@ -56,6 +43,8 @@ The Core API allows you to interact with local data storage. Here are a couple o
|
|||||||
You can use the store.insertOne function to insert data into a specific collection in the local data store.
|
You can use the store.insertOne function to insert data into a specific collection in the local data store.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
import { store } from "@janhq/plugin-core";
|
||||||
|
|
||||||
function insertData() {
|
function insertData() {
|
||||||
store.insertOne("conversations", { name: "meow" });
|
store.insertOne("conversations", { name: "meow" });
|
||||||
// Insert a new document with { name: "meow" } into the "conversations" collection.
|
// Insert a new document with { name: "meow" } into the "conversations" collection.
|
||||||
@ -70,6 +59,8 @@ store.getOne(collectionName, key) retrieves a single document that matches the p
|
|||||||
store.getMany(collectionName, selector, sort) retrieves multiple documents that match the provided selector in the specified collection.
|
store.getMany(collectionName, selector, sort) retrieves multiple documents that match the provided selector in the specified collection.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
import { store } from "@janhq/plugin-core";
|
||||||
|
|
||||||
function getData() {
|
function getData() {
|
||||||
const selector = { name: "meow" };
|
const selector = { name: "meow" };
|
||||||
const data = store.findMany("conversations", selector);
|
const data = store.findMany("conversations", selector);
|
||||||
@ -108,6 +99,96 @@ function deleteData() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Events
|
||||||
|
|
||||||
|
You can subscribe to NewMessageRequest events by defining a function to handle the event and registering it with the events object:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { events } from "@janhq/plugin-core";
|
||||||
|
|
||||||
|
function handleMessageRequest(message: NewMessageRequest) {
|
||||||
|
// Your logic here. For example:
|
||||||
|
// const response = openai.createChatCompletion({...})
|
||||||
|
}
|
||||||
|
function registerListener() {
|
||||||
|
events.on(EventName.OnNewMessageRequest, handleMessageRequest);
|
||||||
|
}
|
||||||
|
// Register the listener function with the relevant extension points.
|
||||||
|
export function init({ register }) {
|
||||||
|
registerListener();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In this example, we're defining a function called handleMessageRequest that takes a NewMessageRequest object as its argument. We're also defining a function called registerListener that registers the handleMessageRequest function as a listener for NewMessageRequest events using the on method of the events object.
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { events } from "@janhq/plugin-core";
|
||||||
|
|
||||||
|
function handleMessageRequest(data: NewMessageRequest) {
|
||||||
|
// Your logic here. For example:
|
||||||
|
const response = openai.createChatCompletion({...})
|
||||||
|
const message: NewMessageResponse = {
|
||||||
|
...data,
|
||||||
|
message: response.data.choices[0].message.content
|
||||||
|
}
|
||||||
|
// Now emit event so the app can display in the conversation
|
||||||
|
events.emit(EventName.OnNewMessageResponse, message)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Preferences
|
||||||
|
|
||||||
|
To register plugin preferences, you can use the preferences object from the @janhq/plugin-core package. Here's an example of how to register and retrieve plugin preferences:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { PluginService, preferences } from "@janhq/plugin-core";
|
||||||
|
|
||||||
|
const pluginName = "your-first-plugin";
|
||||||
|
const preferenceKey = "";
|
||||||
|
const preferenceName = "Your First Preference";
|
||||||
|
const preferenceDescription = "This is for example only";
|
||||||
|
const defaultValue = "";
|
||||||
|
|
||||||
|
export function init({ register }: { register: RegisterExtensionPoint }) {
|
||||||
|
// Register preference update handlers. E.g. update plugin instance with new configuration
|
||||||
|
register(PluginService.OnPreferencesUpdate, pluginName, onPreferencesUpdate);
|
||||||
|
|
||||||
|
// Register plugin preferences. E.g. Plugin need apiKey to connect to your service
|
||||||
|
preferences.registerPreferences <
|
||||||
|
string >
|
||||||
|
(register, pluginName, preferenceKey, preferenceName, preferenceDescription, defaultValue);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In this example, we're registering preference update handlers and plugin preferences using the preferences object. We're also defining a PluginName constant to use as the name of the plugin.
|
||||||
|
|
||||||
|
To retrieve the values of the registered preferences, we're using the get method of the preferences object and passing in the name of the plugin and the name of the preference.
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { preferences } from "@janhq/plugin-core";
|
||||||
|
|
||||||
|
const pluginName = "your-first-plugin";
|
||||||
|
const preferenceKey = "apiKey";
|
||||||
|
|
||||||
|
const setup = async () => {
|
||||||
|
// Retrieve apiKey
|
||||||
|
const apiKey: string = (await preferences.get(pluginName, preferenceKey)) ?? "";
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Access Core API
|
||||||
|
|
||||||
|
To access the Core API in your plugin, you can follow the code examples and explanations provided below.
|
||||||
|
|
||||||
|
##### Import Core API and Store Module
|
||||||
|
|
||||||
|
In your main entry code (e.g., `index.ts`), start by importing the necessary modules and functions from the `@janhq/plugin-core` library.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// index.ts
|
||||||
|
import { core } from "@janhq/plugin-core";
|
||||||
|
```
|
||||||
|
|
||||||
#### Perform File Operations
|
#### Perform File Operations
|
||||||
|
|
||||||
The Core API also provides functions to perform file operations. Here are a couple of examples:
|
The Core API also provides functions to perform file operations. Here are a couple of examples:
|
||||||
@ -132,7 +213,7 @@ function deleteModel(filePath: string) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Execute plugin module in main process
|
#### Execute plugin module in main process
|
||||||
|
|
||||||
To execute a plugin module in the main process of your application, you can follow the steps outlined below.
|
To execute a plugin module in the main process of your application, you can follow the steps outlined below.
|
||||||
|
|
||||||
@ -180,8 +261,8 @@ function getConvMessages(id: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getConvMessages
|
getConvMessages,
|
||||||
}
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
## CoreService API
|
## CoreService API
|
||||||
@ -224,7 +305,6 @@ The `DataService` enum represents methods related to managing conversations and
|
|||||||
|
|
||||||
The `InferenceService` enum exports:
|
The `InferenceService` enum exports:
|
||||||
|
|
||||||
- `InferenceUrl`: The URL for the inference server.
|
|
||||||
- `InitModel`: Initializes a model for inference.
|
- `InitModel`: Initializes a model for inference.
|
||||||
- `StopModel`: Stops a running inference model.
|
- `StopModel`: Stops a running inference model.
|
||||||
|
|
||||||
@ -258,4 +338,11 @@ The `SystemMonitoringService` enum includes methods for monitoring system resour
|
|||||||
- `GetResourcesInfo`: Gets information about system resources.
|
- `GetResourcesInfo`: Gets information about system resources.
|
||||||
- `GetCurrentLoad`: Gets the current system load.
|
- `GetCurrentLoad`: Gets the current system load.
|
||||||
|
|
||||||
|
## PluginService
|
||||||
|
|
||||||
|
The `PluginService` enum includes plugin cycle handlers:
|
||||||
|
|
||||||
|
- `OnStart`: Handler for starting. E.g. Create a collection.
|
||||||
|
- `OnPreferencesUpdate`: Handler for preferences update. E.g. Update instances with new configurations.
|
||||||
|
|
||||||
For more detailed information on each of these components, please refer to the source code.
|
For more detailed information on each of these components, please refer to the source code.
|
||||||
|
|||||||
@ -7,11 +7,7 @@
|
|||||||
* @returns Promise<any>
|
* @returns Promise<any>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
const invokePluginFunc: (
|
const invokePluginFunc: (plugin: string, method: string, ...args: any[]) => Promise<any> = (plugin, method, ...args) =>
|
||||||
plugin: string,
|
|
||||||
method: string,
|
|
||||||
...args: any[]
|
|
||||||
) => Promise<any> = (plugin, method, ...args) =>
|
|
||||||
window.coreAPI?.invokePluginFunc(plugin, method, ...args) ??
|
window.coreAPI?.invokePluginFunc(plugin, method, ...args) ??
|
||||||
window.electronAPI?.invokePluginFunc(plugin, method, ...args);
|
window.electronAPI?.invokePluginFunc(plugin, method, ...args);
|
||||||
|
|
||||||
|
|||||||
71
plugin-core/events.ts
Normal file
71
plugin-core/events.ts
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/**
|
||||||
|
* The `EventName` enumeration contains the names of all the available events in the Jan platform.
|
||||||
|
*/
|
||||||
|
export enum EventName {
|
||||||
|
OnNewConversation = "onNewConversation",
|
||||||
|
OnNewMessageRequest = "onNewMessageRequest",
|
||||||
|
OnNewMessageResponse = "onNewMessageResponse",
|
||||||
|
OnMessageResponseUpdate = "onMessageResponseUpdate",
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `NewMessageRequest` type defines the shape of a new message request object.
|
||||||
|
*/
|
||||||
|
export type NewMessageRequest = {
|
||||||
|
_id?: string;
|
||||||
|
conversationId?: string;
|
||||||
|
user?: string;
|
||||||
|
avatar?: string;
|
||||||
|
message?: string;
|
||||||
|
createdAt?: string;
|
||||||
|
updatedAt?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `NewMessageRequest` type defines the shape of a new message request object.
|
||||||
|
*/
|
||||||
|
export type NewMessageResponse = {
|
||||||
|
_id?: string;
|
||||||
|
conversationId?: string;
|
||||||
|
user?: string;
|
||||||
|
avatar?: string;
|
||||||
|
message?: string;
|
||||||
|
createdAt?: string;
|
||||||
|
updatedAt?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an observer for an event.
|
||||||
|
*
|
||||||
|
* @param eventName The name of the event to observe.
|
||||||
|
* @param handler The handler function to call when the event is observed.
|
||||||
|
*/
|
||||||
|
const on: (eventName: string, handler: Function) => void = (eventName, handler) => {
|
||||||
|
window.corePlugin?.events?.on(eventName, handler);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an observer for an event.
|
||||||
|
*
|
||||||
|
* @param eventName The name of the event to stop observing.
|
||||||
|
* @param handler The handler function to call when the event is observed.
|
||||||
|
*/
|
||||||
|
const off: (eventName: string, handler: Function) => void = (eventName, handler) => {
|
||||||
|
window.corePlugin?.events?.off(eventName, handler);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emits an event.
|
||||||
|
*
|
||||||
|
* @param eventName The name of the event to emit.
|
||||||
|
* @param object The object to pass to the event callback.
|
||||||
|
*/
|
||||||
|
const emit: (eventName: string, object: any) => void = (eventName, object) => {
|
||||||
|
window.corePlugin?.events?.emit(eventName, object);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const events = {
|
||||||
|
on,
|
||||||
|
off,
|
||||||
|
emit,
|
||||||
|
};
|
||||||
@ -8,7 +8,8 @@ export type CoreService =
|
|||||||
| InferenceService
|
| InferenceService
|
||||||
| ModelManagementService
|
| ModelManagementService
|
||||||
| SystemMonitoringService
|
| SystemMonitoringService
|
||||||
| PreferenceService;
|
| PreferenceService
|
||||||
|
| PluginService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the available methods for the StoreService.
|
* Represents the available methods for the StoreService.
|
||||||
@ -107,11 +108,6 @@ export enum DataService {
|
|||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
export enum InferenceService {
|
export enum InferenceService {
|
||||||
/**
|
|
||||||
* The URL for the inference server.
|
|
||||||
*/
|
|
||||||
InferenceUrl = "inferenceUrl",
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a model for inference.
|
* Initializes a model for inference.
|
||||||
*/
|
*/
|
||||||
@ -216,6 +212,32 @@ export enum SystemMonitoringService {
|
|||||||
GetCurrentLoad = "getCurrentLoad",
|
GetCurrentLoad = "getCurrentLoad",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PluginService exports.
|
||||||
|
* @enum {string}
|
||||||
|
*/
|
||||||
|
export enum PluginService {
|
||||||
|
/**
|
||||||
|
* The plugin is being started.
|
||||||
|
*/
|
||||||
|
OnStart = "pluginOnStart",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The plugin is being started.
|
||||||
|
*/
|
||||||
|
OnPreferencesUpdate = "pluginPreferencesUpdate",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The plugin is being stopped.
|
||||||
|
*/
|
||||||
|
OnStop = "pluginOnStop",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The plugin is being destroyed.
|
||||||
|
*/
|
||||||
|
OnDestroy = "pluginOnDestroy",
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store module exports.
|
* Store module exports.
|
||||||
* @module
|
* @module
|
||||||
@ -227,3 +249,15 @@ export { store } from "./store";
|
|||||||
* @module
|
* @module
|
||||||
*/
|
*/
|
||||||
export { core, RegisterExtensionPoint } from "./core";
|
export { core, RegisterExtensionPoint } from "./core";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Events module exports.
|
||||||
|
* @module
|
||||||
|
*/
|
||||||
|
export { events, EventName, NewMessageRequest, NewMessageResponse } from "./events";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preferences module exports.
|
||||||
|
* @module
|
||||||
|
*/
|
||||||
|
export { preferences } from "./preferences";
|
||||||
|
|||||||
20
plugin-core/package-lock.json
generated
20
plugin-core/package-lock.json
generated
@ -1,15 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "@janhq/plugin-core",
|
"name": "@janhq/plugin-core",
|
||||||
"version": "0.1.0",
|
"version": "0.1.6",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@janhq/plugin-core",
|
"name": "@janhq/plugin-core",
|
||||||
"version": "0.1.0",
|
"version": "0.1.6",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^12.0.2"
|
"@types/node": "^12.0.2",
|
||||||
|
"typescript": "^5.2.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
@ -17,6 +18,19 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz",
|
||||||
"integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==",
|
"integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/typescript": {
|
||||||
|
"version": "5.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
|
||||||
|
"integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"tsc": "bin/tsc",
|
||||||
|
"tsserver": "bin/tsserver"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.17"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@janhq/plugin-core",
|
"name": "@janhq/plugin-core",
|
||||||
"version": "0.1.6",
|
"version": "0.1.8",
|
||||||
"description": "Plugin core lib",
|
"description": "Plugin core lib",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"jan",
|
"jan",
|
||||||
|
|||||||
84
plugin-core/preferences.ts
Normal file
84
plugin-core/preferences.ts
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import { store } from "./store";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of the specified preference for the specified plugin.
|
||||||
|
*
|
||||||
|
* @param pluginName The name of the plugin.
|
||||||
|
* @param preferenceKey The key of the preference.
|
||||||
|
* @returns A promise that resolves to the value of the preference.
|
||||||
|
*/
|
||||||
|
function get(pluginName: string, preferenceKey: string): Promise<any> {
|
||||||
|
return store
|
||||||
|
.createCollection("preferences", {})
|
||||||
|
.then(() => store.findOne("preferences", `${pluginName}.${preferenceKey}`))
|
||||||
|
.then((doc) => doc?.value ?? "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of the specified preference for the specified plugin.
|
||||||
|
*
|
||||||
|
* @param pluginName The name of the plugin.
|
||||||
|
* @param preferenceKey The key of the preference.
|
||||||
|
* @param value The value of the preference.
|
||||||
|
* @returns A promise that resolves when the preference has been set.
|
||||||
|
*/
|
||||||
|
function set(pluginName: string, preferenceKey: string, value: any): Promise<any> {
|
||||||
|
return store
|
||||||
|
.createCollection("preferences", {})
|
||||||
|
.then(() =>
|
||||||
|
store
|
||||||
|
.findOne("preferences", `${pluginName}.${preferenceKey}`)
|
||||||
|
.then((doc) =>
|
||||||
|
doc
|
||||||
|
? store.updateOne("preferences", `${pluginName}.${preferenceKey}`, { value })
|
||||||
|
: store.insertOne("preferences", { _id: `${pluginName}.${preferenceKey}`, value })
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears all preferences for the specified plugin.
|
||||||
|
*
|
||||||
|
* @param pluginName The name of the plugin.
|
||||||
|
* @returns A promise that resolves when the preferences have been cleared.
|
||||||
|
*/
|
||||||
|
function clear(pluginName: string): Promise<void> {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a preference with the specified default value.
|
||||||
|
*
|
||||||
|
* @param register The function to use for registering the preference.
|
||||||
|
* @param pluginName The name of the plugin.
|
||||||
|
* @param preferenceKey The key of the preference.
|
||||||
|
* @param preferenceName The name of the preference.
|
||||||
|
* @param preferenceDescription The description of the preference.
|
||||||
|
* @param defaultValue The default value of the preference.
|
||||||
|
*/
|
||||||
|
function registerPreferences<T>(
|
||||||
|
register: Function,
|
||||||
|
pluginName: string,
|
||||||
|
preferenceKey: string,
|
||||||
|
preferenceName: string,
|
||||||
|
preferenceDescription: string,
|
||||||
|
defaultValue: T
|
||||||
|
) {
|
||||||
|
register("PluginPreferences", `${pluginName}.${preferenceKey}`, () => ({
|
||||||
|
pluginName,
|
||||||
|
preferenceKey,
|
||||||
|
preferenceName,
|
||||||
|
preferenceDescription,
|
||||||
|
defaultValue,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object that provides methods for getting, setting, and clearing preferences.
|
||||||
|
*/
|
||||||
|
export const preferences = {
|
||||||
|
get,
|
||||||
|
set,
|
||||||
|
clear,
|
||||||
|
registerPreferences,
|
||||||
|
};
|
||||||
1
plugin-core/types/index.d.ts
vendored
1
plugin-core/types/index.d.ts
vendored
@ -3,6 +3,7 @@ export {};
|
|||||||
declare global {
|
declare global {
|
||||||
interface CorePlugin {
|
interface CorePlugin {
|
||||||
store?: any | undefined;
|
store?: any | undefined;
|
||||||
|
events?: any | undefined;
|
||||||
}
|
}
|
||||||
interface Window {
|
interface Window {
|
||||||
corePlugin?: CorePlugin;
|
corePlugin?: CorePlugin;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { core, store, RegisterExtensionPoint, StoreService, DataService } from "@janhq/plugin-core";
|
import { core, store, RegisterExtensionPoint, StoreService, DataService, PluginService } from "@janhq/plugin-core";
|
||||||
|
|
||||||
// Provide an async method to manipulate the price provided by the extension point
|
const PluginName = "@janhq/data-plugin";
|
||||||
const MODULE_PATH = "data-plugin/dist/cjs/module.js";
|
const MODULE_PATH = "@janhq/data-plugin/dist/cjs/module.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a collection on data store
|
* Create a collection on data store
|
||||||
@ -12,7 +12,6 @@ const MODULE_PATH = "data-plugin/dist/cjs/module.js";
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function createCollection({ name, schema }: { name: string; schema?: { [key: string]: any } }): Promise<void> {
|
function createCollection({ name, schema }: { name: string; schema?: { [key: string]: any } }): Promise<void> {
|
||||||
console.log("renderer: creating collection:", name, schema);
|
|
||||||
return core.invokePluginFunc(MODULE_PATH, "createCollection", name, schema);
|
return core.invokePluginFunc(MODULE_PATH, "createCollection", name, schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,8 +136,7 @@ function onStart() {
|
|||||||
|
|
||||||
// Register all the above functions and objects with the relevant extension points
|
// Register all the above functions and objects with the relevant extension points
|
||||||
export function init({ register }: { register: RegisterExtensionPoint }) {
|
export function init({ register }: { register: RegisterExtensionPoint }) {
|
||||||
onStart();
|
register(PluginService.OnStart, PluginName, onStart);
|
||||||
|
|
||||||
register(StoreService.CreateCollection, createCollection.name, createCollection);
|
register(StoreService.CreateCollection, createCollection.name, createCollection);
|
||||||
register(StoreService.DeleteCollection, deleteCollection.name, deleteCollection);
|
register(StoreService.DeleteCollection, deleteCollection.name, deleteCollection);
|
||||||
register(StoreService.InsertOne, insertOne.name, insertOne);
|
register(StoreService.InsertOne, insertOne.name, insertOne);
|
||||||
@ -1,20 +1,20 @@
|
|||||||
{
|
{
|
||||||
"name": "data-plugin",
|
"name": "@janhq/data-plugin",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "data-plugin",
|
"name": "@janhq/data-plugin",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundleDependencies": [
|
"bundleDependencies": [
|
||||||
"rxdb",
|
"pouchdb-node",
|
||||||
"rxjs"
|
"pouchdb-find"
|
||||||
],
|
],
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@janhq/plugin-core": "file:../../../../plugin-core",
|
"@janhq/plugin-core": "^0.1.8",
|
||||||
"pouchdb-find": "^8.0.1",
|
"pouchdb-find": "^8.0.1",
|
||||||
"pouchdb-node": "^8.0.1"
|
"pouchdb-node": "^8.0.1"
|
||||||
},
|
},
|
||||||
@ -29,14 +29,6 @@
|
|||||||
"webpack-cli": "^5.1.4"
|
"webpack-cli": "^5.1.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"../../../../plugin-core": {
|
|
||||||
"name": "@janhq/plugin-core",
|
|
||||||
"version": "0.1.0",
|
|
||||||
"license": "MIT",
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/node": "^12.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@cspotcode/source-map-support": {
|
"node_modules/@cspotcode/source-map-support": {
|
||||||
"version": "0.8.1",
|
"version": "0.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||||
@ -59,8 +51,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@janhq/plugin-core": {
|
"node_modules/@janhq/plugin-core": {
|
||||||
"resolved": "../../../../plugin-core",
|
"version": "0.1.8",
|
||||||
"link": true
|
"resolved": "https://registry.npmjs.org/@janhq/plugin-core/-/plugin-core-0.1.8.tgz",
|
||||||
|
"integrity": "sha512-wJe+8ndMQLGLSV36Jt1V3s5lmH+nQw87ol2NMhHuVWXfwf+DAO1GTdTeHfemHWdcB/oUY1HVRvsNh8DvBgbh/w=="
|
||||||
},
|
},
|
||||||
"node_modules/@jridgewell/gen-mapping": {
|
"node_modules/@jridgewell/gen-mapping": {
|
||||||
"version": "0.3.3",
|
"version": "0.3.3",
|
||||||
@ -177,9 +170,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "20.8.4",
|
"version": "20.8.6",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.6.tgz",
|
||||||
"integrity": "sha512-ZVPnqU58giiCjSxjVUESDtdPk4QR5WQhhINbc9UBrKLU68MX5BF6kbQzTrkwbolyr0X8ChBpXfavr5mZFKZQ5A==",
|
"integrity": "sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~5.25.1"
|
"undici-types": "~5.25.1"
|
||||||
@ -397,6 +390,7 @@
|
|||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
||||||
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
|
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"event-target-shim": "^5.0.0"
|
"event-target-shim": "^5.0.0"
|
||||||
},
|
},
|
||||||
@ -408,6 +402,7 @@
|
|||||||
"version": "6.2.3",
|
"version": "6.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz",
|
||||||
"integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==",
|
"integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"buffer": "^5.5.0",
|
"buffer": "^5.5.0",
|
||||||
"immediate": "^3.2.3",
|
"immediate": "^3.2.3",
|
||||||
@ -674,7 +669,8 @@
|
|||||||
"type": "consulting",
|
"type": "consulting",
|
||||||
"url": "https://feross.org/support"
|
"url": "https://feross.org/support"
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/binary-extensions": {
|
"node_modules/binary-extensions": {
|
||||||
"version": "1.13.1",
|
"version": "1.13.1",
|
||||||
@ -769,6 +765,7 @@
|
|||||||
"url": "https://feross.org/support"
|
"url": "https://feross.org/support"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"base64-js": "^1.3.1",
|
"base64-js": "^1.3.1",
|
||||||
"ieee754": "^1.1.13"
|
"ieee754": "^1.1.13"
|
||||||
@ -777,7 +774,8 @@
|
|||||||
"node_modules/buffer-from": {
|
"node_modules/buffer-from": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
|
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/cache-base": {
|
"node_modules/cache-base": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
@ -809,9 +807,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001547",
|
"version": "1.0.30001549",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001547.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001549.tgz",
|
||||||
"integrity": "sha512-W7CrtIModMAxobGhz8iXmDfuJiiKg1WADMO/9x7/CLNin5cpSbuBjooyoIUVB5eyCc36QuTVlkVa1iB2S5+/eA==",
|
"integrity": "sha512-qRp48dPYSCYaP+KurZLhDYdVE+yEyht/3NlmcJgVQ2VMGt6JL36ndQ/7rgspdZsJuxDPFIo/OzBT2+GmIJ53BA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -966,6 +964,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
|
||||||
"integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==",
|
"integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==",
|
||||||
|
"inBundle": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.10"
|
"node": ">= 0.10"
|
||||||
}
|
}
|
||||||
@ -1083,7 +1082,8 @@
|
|||||||
"node_modules/core-util-is": {
|
"node_modules/core-util-is": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
|
||||||
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
|
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/cpx": {
|
"node_modules/cpx": {
|
||||||
"version": "1.5.0",
|
"version": "1.5.0",
|
||||||
@ -1158,6 +1158,7 @@
|
|||||||
"version": "5.3.0",
|
"version": "5.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz",
|
||||||
"integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==",
|
"integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"abstract-leveldown": "~6.2.1",
|
"abstract-leveldown": "~6.2.1",
|
||||||
"inherits": "^2.0.3"
|
"inherits": "^2.0.3"
|
||||||
@ -1218,7 +1219,8 @@
|
|||||||
"node_modules/double-ended-queue": {
|
"node_modules/double-ended-queue": {
|
||||||
"version": "2.1.0-0",
|
"version": "2.1.0-0",
|
||||||
"resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz",
|
"resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz",
|
||||||
"integrity": "sha512-+BNfZ+deCo8hMNpDqDnvT+c0XpJ5cUa6mqYq89bho2Ifze4URTqRkcwR399hWoTrTkbZ/XJYDgP6rc7pRgffEQ=="
|
"integrity": "sha512-+BNfZ+deCo8hMNpDqDnvT+c0XpJ5cUa6mqYq89bho2Ifze4URTqRkcwR399hWoTrTkbZ/XJYDgP6rc7pRgffEQ==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/duplexer": {
|
"node_modules/duplexer": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
@ -1227,15 +1229,16 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.4.551",
|
"version": "1.4.554",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.551.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.554.tgz",
|
||||||
"integrity": "sha512-/Ng/W/kFv7wdEHYzxdK7Cv0BHEGSkSB3M0Ssl8Ndr1eMiYeas/+Mv4cNaDqamqWx6nd2uQZfPz6g25z25M/sdw==",
|
"integrity": "sha512-Q0umzPJjfBrrj8unkONTgbKQXzXRrH7sVV7D9ea2yBV3Oaogz991yhbpfvo2LMNkJItmruXTEzVpP9cp7vaIiQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/encoding-down": {
|
"node_modules/encoding-down": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz",
|
||||||
"integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==",
|
"integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"abstract-leveldown": "^6.2.1",
|
"abstract-leveldown": "^6.2.1",
|
||||||
"inherits": "^2.0.3",
|
"inherits": "^2.0.3",
|
||||||
@ -1250,6 +1253,7 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/end-stream/-/end-stream-0.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/end-stream/-/end-stream-0.1.0.tgz",
|
||||||
"integrity": "sha512-Brl10T8kYnc75IepKizW6Y9liyW8ikz1B7n/xoHrJxoVSSjoqPn30sb7XVFfQERK4QfUMYRGs9dhWwtt2eu6uA==",
|
"integrity": "sha512-Brl10T8kYnc75IepKizW6Y9liyW8ikz1B7n/xoHrJxoVSSjoqPn30sb7XVFfQERK4QfUMYRGs9dhWwtt2eu6uA==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"write-stream": "~0.4.3"
|
"write-stream": "~0.4.3"
|
||||||
}
|
}
|
||||||
@ -1283,6 +1287,7 @@
|
|||||||
"version": "0.1.8",
|
"version": "0.1.8",
|
||||||
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
|
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
|
||||||
"integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
|
"integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"prr": "~1.0.1"
|
"prr": "~1.0.1"
|
||||||
},
|
},
|
||||||
@ -1352,6 +1357,7 @@
|
|||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
|
||||||
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
|
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
|
||||||
|
"inBundle": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
@ -1451,6 +1457,7 @@
|
|||||||
"version": "0.11.0",
|
"version": "0.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-0.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-0.11.0.tgz",
|
||||||
"integrity": "sha512-BQm7iZLFhMWFy5CZ/162sAGjBfdNWb7a8LEqqnzsHFhxT/X/SVj/z2t2nu3aJvjlbQkrAlTUApplPRjWyH4mhA==",
|
"integrity": "sha512-BQm7iZLFhMWFy5CZ/162sAGjBfdNWb7a8LEqqnzsHFhxT/X/SVj/z2t2nu3aJvjlbQkrAlTUApplPRjWyH4mhA==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tough-cookie": "^2.3.3 || ^3.0.1 || ^4.0.0"
|
"tough-cookie": "^2.3.3 || ^3.0.1 || ^4.0.0"
|
||||||
},
|
},
|
||||||
@ -1792,7 +1799,8 @@
|
|||||||
"type": "consulting",
|
"type": "consulting",
|
||||||
"url": "https://feross.org/support"
|
"url": "https://feross.org/support"
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/ignore-walk": {
|
"node_modules/ignore-walk": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
@ -1806,7 +1814,8 @@
|
|||||||
"node_modules/immediate": {
|
"node_modules/immediate": {
|
||||||
"version": "3.3.0",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz",
|
||||||
"integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q=="
|
"integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/import-local": {
|
"node_modules/import-local": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
@ -1840,7 +1849,8 @@
|
|||||||
"node_modules/inherits": {
|
"node_modules/inherits": {
|
||||||
"version": "2.0.4",
|
"version": "2.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/ini": {
|
"node_modules/ini": {
|
||||||
"version": "1.3.8",
|
"version": "1.3.8",
|
||||||
@ -2078,7 +2088,8 @@
|
|||||||
"node_modules/isarray": {
|
"node_modules/isarray": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||||
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
|
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/isexe": {
|
"node_modules/isexe": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
@ -2155,6 +2166,7 @@
|
|||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/level/-/level-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/level/-/level-6.0.1.tgz",
|
||||||
"integrity": "sha512-psRSqJZCsC/irNhfHzrVZbmPYXDcEYhA5TVNwr+V92jF44rbf86hqGp8fiT702FyiArScYIlPSBTDUASCVNSpw==",
|
"integrity": "sha512-psRSqJZCsC/irNhfHzrVZbmPYXDcEYhA5TVNwr+V92jF44rbf86hqGp8fiT702FyiArScYIlPSBTDUASCVNSpw==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"level-js": "^5.0.0",
|
"level-js": "^5.0.0",
|
||||||
"level-packager": "^5.1.0",
|
"level-packager": "^5.1.0",
|
||||||
@ -2172,6 +2184,7 @@
|
|||||||
"version": "9.0.2",
|
"version": "9.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz",
|
||||||
"integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==",
|
"integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"buffer": "^5.6.0"
|
"buffer": "^5.6.0"
|
||||||
},
|
},
|
||||||
@ -2183,6 +2196,7 @@
|
|||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz",
|
||||||
"integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==",
|
"integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==",
|
||||||
|
"inBundle": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
@ -2191,6 +2205,7 @@
|
|||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz",
|
||||||
"integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==",
|
"integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"errno": "~0.1.1"
|
"errno": "~0.1.1"
|
||||||
},
|
},
|
||||||
@ -2202,6 +2217,7 @@
|
|||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz",
|
||||||
"integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==",
|
"integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"inherits": "^2.0.4",
|
"inherits": "^2.0.4",
|
||||||
"readable-stream": "^3.4.0",
|
"readable-stream": "^3.4.0",
|
||||||
@ -2215,6 +2231,7 @@
|
|||||||
"version": "3.6.2",
|
"version": "3.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"inherits": "^2.0.3",
|
"inherits": "^2.0.3",
|
||||||
"string_decoder": "^1.1.1",
|
"string_decoder": "^1.1.1",
|
||||||
@ -2228,6 +2245,7 @@
|
|||||||
"version": "5.0.2",
|
"version": "5.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/level-js/-/level-js-5.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/level-js/-/level-js-5.0.2.tgz",
|
||||||
"integrity": "sha512-SnBIDo2pdO5VXh02ZmtAyPP6/+6YTJg2ibLtl9C34pWvmtMEmRTWpra+qO/hifkUtBTOtfx6S9vLDjBsBK4gRg==",
|
"integrity": "sha512-SnBIDo2pdO5VXh02ZmtAyPP6/+6YTJg2ibLtl9C34pWvmtMEmRTWpra+qO/hifkUtBTOtfx6S9vLDjBsBK4gRg==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"abstract-leveldown": "~6.2.3",
|
"abstract-leveldown": "~6.2.3",
|
||||||
"buffer": "^5.5.0",
|
"buffer": "^5.5.0",
|
||||||
@ -2239,6 +2257,7 @@
|
|||||||
"version": "5.1.1",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/level-packager/-/level-packager-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/level-packager/-/level-packager-5.1.1.tgz",
|
||||||
"integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==",
|
"integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"encoding-down": "^6.3.0",
|
"encoding-down": "^6.3.0",
|
||||||
"levelup": "^4.3.2"
|
"levelup": "^4.3.2"
|
||||||
@ -2251,6 +2270,7 @@
|
|||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz",
|
||||||
"integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==",
|
"integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"xtend": "^4.0.2"
|
"xtend": "^4.0.2"
|
||||||
},
|
},
|
||||||
@ -2262,6 +2282,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/level-write-stream/-/level-write-stream-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/level-write-stream/-/level-write-stream-1.0.0.tgz",
|
||||||
"integrity": "sha512-bBNKOEOMl8msO+uIM9YX/gUO6ckokZ/4pCwTm/lwvs46x6Xs8Zy0sn3Vh37eDqse4mhy4fOMIb/JsSM2nyQFtw==",
|
"integrity": "sha512-bBNKOEOMl8msO+uIM9YX/gUO6ckokZ/4pCwTm/lwvs46x6Xs8Zy0sn3Vh37eDqse4mhy4fOMIb/JsSM2nyQFtw==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"end-stream": "~0.1.0"
|
"end-stream": "~0.1.0"
|
||||||
}
|
}
|
||||||
@ -2271,6 +2292,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/leveldown/-/leveldown-5.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/leveldown/-/leveldown-5.6.0.tgz",
|
||||||
"integrity": "sha512-iB8O/7Db9lPaITU1aA2txU/cBEXAt4vWwKQRrrWuS6XDgbP4QZGj9BL2aNbwb002atoQ/lIotJkfyzz+ygQnUQ==",
|
"integrity": "sha512-iB8O/7Db9lPaITU1aA2txU/cBEXAt4vWwKQRrrWuS6XDgbP4QZGj9BL2aNbwb002atoQ/lIotJkfyzz+ygQnUQ==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"abstract-leveldown": "~6.2.1",
|
"abstract-leveldown": "~6.2.1",
|
||||||
"napi-macros": "~2.0.0",
|
"napi-macros": "~2.0.0",
|
||||||
@ -2284,6 +2306,7 @@
|
|||||||
"version": "4.4.0",
|
"version": "4.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz",
|
||||||
"integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==",
|
"integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"deferred-leveldown": "~5.3.0",
|
"deferred-leveldown": "~5.3.0",
|
||||||
"level-errors": "~2.0.0",
|
"level-errors": "~2.0.0",
|
||||||
@ -2337,7 +2360,8 @@
|
|||||||
"node_modules/ltgt": {
|
"node_modules/ltgt": {
|
||||||
"version": "2.2.1",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
|
||||||
"integrity": "sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA=="
|
"integrity": "sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/make-error": {
|
"node_modules/make-error": {
|
||||||
"version": "1.3.6",
|
"version": "1.3.6",
|
||||||
@ -2565,7 +2589,8 @@
|
|||||||
"node_modules/napi-macros": {
|
"node_modules/napi-macros": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz",
|
||||||
"integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg=="
|
"integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/needle": {
|
"node_modules/needle": {
|
||||||
"version": "2.9.1",
|
"version": "2.9.1",
|
||||||
@ -2594,6 +2619,7 @@
|
|||||||
"version": "2.6.7",
|
"version": "2.6.7",
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"whatwg-url": "^5.0.0"
|
"whatwg-url": "^5.0.0"
|
||||||
},
|
},
|
||||||
@ -2613,6 +2639,7 @@
|
|||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.1.1.tgz",
|
||||||
"integrity": "sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ==",
|
"integrity": "sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ==",
|
||||||
|
"inBundle": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"node-gyp-build": "bin.js",
|
"node-gyp-build": "bin.js",
|
||||||
"node-gyp-build-optional": "optional.js",
|
"node-gyp-build-optional": "optional.js",
|
||||||
@ -3041,6 +3068,7 @@
|
|||||||
"version": "8.0.1",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/pouchdb-abstract-mapreduce/-/pouchdb-abstract-mapreduce-8.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/pouchdb-abstract-mapreduce/-/pouchdb-abstract-mapreduce-8.0.1.tgz",
|
||||||
"integrity": "sha512-BxJRHdfiC8gID8h4DPS0Xy6wsa2VBHRHMv9hsm0BhGTWTqS4k8ivItVSeU2dMoXiTBYp+7SerYmovUQNGSX1GA==",
|
"integrity": "sha512-BxJRHdfiC8gID8h4DPS0Xy6wsa2VBHRHMv9hsm0BhGTWTqS4k8ivItVSeU2dMoXiTBYp+7SerYmovUQNGSX1GA==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pouchdb-binary-utils": "8.0.1",
|
"pouchdb-binary-utils": "8.0.1",
|
||||||
"pouchdb-collate": "8.0.1",
|
"pouchdb-collate": "8.0.1",
|
||||||
@ -3056,6 +3084,7 @@
|
|||||||
"version": "8.0.1",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/pouchdb-binary-utils/-/pouchdb-binary-utils-8.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/pouchdb-binary-utils/-/pouchdb-binary-utils-8.0.1.tgz",
|
||||||
"integrity": "sha512-WsuR/S0aoUlcA0Alt99czkXsfuXWcrYXAcvGiTW02zawVXOafCnb/qHjA09TUaV0oy5HeHmYaNnDckoOUqspeA==",
|
"integrity": "sha512-WsuR/S0aoUlcA0Alt99czkXsfuXWcrYXAcvGiTW02zawVXOafCnb/qHjA09TUaV0oy5HeHmYaNnDckoOUqspeA==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"buffer-from": "1.1.2"
|
"buffer-from": "1.1.2"
|
||||||
}
|
}
|
||||||
@ -3063,22 +3092,26 @@
|
|||||||
"node_modules/pouchdb-collate": {
|
"node_modules/pouchdb-collate": {
|
||||||
"version": "8.0.1",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/pouchdb-collate/-/pouchdb-collate-8.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/pouchdb-collate/-/pouchdb-collate-8.0.1.tgz",
|
||||||
"integrity": "sha512-DTuNz1UJjBTGZMUlWS1klSE1rPsmHy8IIDie3MFH1ZTz/C+SwGgGwkiAyUDv/n00D18EMLgXq5mu+r7L6K1BwQ=="
|
"integrity": "sha512-DTuNz1UJjBTGZMUlWS1klSE1rPsmHy8IIDie3MFH1ZTz/C+SwGgGwkiAyUDv/n00D18EMLgXq5mu+r7L6K1BwQ==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/pouchdb-collections": {
|
"node_modules/pouchdb-collections": {
|
||||||
"version": "8.0.1",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/pouchdb-collections/-/pouchdb-collections-8.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/pouchdb-collections/-/pouchdb-collections-8.0.1.tgz",
|
||||||
"integrity": "sha512-TlkQ2GGHJApJgL0b7bJMQcwX6eMfVenLeoK9mqHfC2fJssui+HWJJ5LYKHOWan11SeB90BQVFbO6rHN6CJQeDg=="
|
"integrity": "sha512-TlkQ2GGHJApJgL0b7bJMQcwX6eMfVenLeoK9mqHfC2fJssui+HWJJ5LYKHOWan11SeB90BQVFbO6rHN6CJQeDg==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/pouchdb-errors": {
|
"node_modules/pouchdb-errors": {
|
||||||
"version": "8.0.1",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/pouchdb-errors/-/pouchdb-errors-8.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/pouchdb-errors/-/pouchdb-errors-8.0.1.tgz",
|
||||||
"integrity": "sha512-H+ZsQxcG/JV3Tn29gnM6c9+lRPCN91ZYOkoIICsLjVRYgOTzN1AvNUD/G5JCB+81aI/u3fxZec0LEaZh6g6NHA=="
|
"integrity": "sha512-H+ZsQxcG/JV3Tn29gnM6c9+lRPCN91ZYOkoIICsLjVRYgOTzN1AvNUD/G5JCB+81aI/u3fxZec0LEaZh6g6NHA==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/pouchdb-fetch": {
|
"node_modules/pouchdb-fetch": {
|
||||||
"version": "8.0.1",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/pouchdb-fetch/-/pouchdb-fetch-8.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/pouchdb-fetch/-/pouchdb-fetch-8.0.1.tgz",
|
||||||
"integrity": "sha512-Px5HLT8MxqTujc8bpPRKoouznDTJa9XBGqCbhl95q6rhjWRfwZEvXjV92z0B5BALAM6D6avMyG0DjuNfUWnMuA==",
|
"integrity": "sha512-Px5HLT8MxqTujc8bpPRKoouznDTJa9XBGqCbhl95q6rhjWRfwZEvXjV92z0B5BALAM6D6avMyG0DjuNfUWnMuA==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"abort-controller": "3.0.0",
|
"abort-controller": "3.0.0",
|
||||||
"fetch-cookie": "0.11.0",
|
"fetch-cookie": "0.11.0",
|
||||||
@ -3089,6 +3122,7 @@
|
|||||||
"version": "8.0.1",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/pouchdb-find/-/pouchdb-find-8.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/pouchdb-find/-/pouchdb-find-8.0.1.tgz",
|
||||||
"integrity": "sha512-i5criYXMOXlbeRrCrXonqaOY+xiMiOyTLybqvtX/NkUsiD4BxJxkq5AxdSlHdJ9703nWJ0k6S+5C8VrpEj8tsQ==",
|
"integrity": "sha512-i5criYXMOXlbeRrCrXonqaOY+xiMiOyTLybqvtX/NkUsiD4BxJxkq5AxdSlHdJ9703nWJ0k6S+5C8VrpEj8tsQ==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pouchdb-abstract-mapreduce": "8.0.1",
|
"pouchdb-abstract-mapreduce": "8.0.1",
|
||||||
"pouchdb-collate": "8.0.1",
|
"pouchdb-collate": "8.0.1",
|
||||||
@ -3103,6 +3137,7 @@
|
|||||||
"version": "8.0.1",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/pouchdb-mapreduce-utils/-/pouchdb-mapreduce-utils-8.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/pouchdb-mapreduce-utils/-/pouchdb-mapreduce-utils-8.0.1.tgz",
|
||||||
"integrity": "sha512-asZcFLy1DA3oe5CeXIRCpfVrBHaHRvSb3Tc/LPD1dZDDtpEkeCuXGtJm+praN0jl41jTBEm0uMdD/YI0J5ZFXw==",
|
"integrity": "sha512-asZcFLy1DA3oe5CeXIRCpfVrBHaHRvSb3Tc/LPD1dZDDtpEkeCuXGtJm+praN0jl41jTBEm0uMdD/YI0J5ZFXw==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pouchdb-collections": "8.0.1",
|
"pouchdb-collections": "8.0.1",
|
||||||
"pouchdb-utils": "8.0.1"
|
"pouchdb-utils": "8.0.1"
|
||||||
@ -3112,6 +3147,7 @@
|
|||||||
"version": "8.0.1",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/pouchdb-md5/-/pouchdb-md5-8.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/pouchdb-md5/-/pouchdb-md5-8.0.1.tgz",
|
||||||
"integrity": "sha512-shVcs/K/iilrcAhDEERpLIrGm/cnDVsXiocOzs7kycJEuBqYnLD9nj58VwWDcum26wfa8T9cznvEGE1jlYVNPQ==",
|
"integrity": "sha512-shVcs/K/iilrcAhDEERpLIrGm/cnDVsXiocOzs7kycJEuBqYnLD9nj58VwWDcum26wfa8T9cznvEGE1jlYVNPQ==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pouchdb-binary-utils": "8.0.1",
|
"pouchdb-binary-utils": "8.0.1",
|
||||||
"spark-md5": "3.0.2"
|
"spark-md5": "3.0.2"
|
||||||
@ -3121,6 +3157,7 @@
|
|||||||
"version": "8.0.1",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/pouchdb-node/-/pouchdb-node-8.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/pouchdb-node/-/pouchdb-node-8.0.1.tgz",
|
||||||
"integrity": "sha512-xYvVmBB/nEZltBYkslE0RKciL7l359BFbG27gyGJlpPHeMUhtVlYHoEiI2gb2x2pEn7hG9B7Odo8keuq4/ot1w==",
|
"integrity": "sha512-xYvVmBB/nEZltBYkslE0RKciL7l359BFbG27gyGJlpPHeMUhtVlYHoEiI2gb2x2pEn7hG9B7Odo8keuq4/ot1w==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"abort-controller": "3.0.0",
|
"abort-controller": "3.0.0",
|
||||||
"buffer-from": "1.1.2",
|
"buffer-from": "1.1.2",
|
||||||
@ -3143,12 +3180,14 @@
|
|||||||
"node_modules/pouchdb-node/node_modules/isarray": {
|
"node_modules/pouchdb-node/node_modules/isarray": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||||
"integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ=="
|
"integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/pouchdb-node/node_modules/readable-stream": {
|
"node_modules/pouchdb-node/node_modules/readable-stream": {
|
||||||
"version": "1.1.14",
|
"version": "1.1.14",
|
||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
|
||||||
"integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==",
|
"integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-util-is": "~1.0.0",
|
"core-util-is": "~1.0.0",
|
||||||
"inherits": "~2.0.1",
|
"inherits": "~2.0.1",
|
||||||
@ -3159,12 +3198,14 @@
|
|||||||
"node_modules/pouchdb-node/node_modules/string_decoder": {
|
"node_modules/pouchdb-node/node_modules/string_decoder": {
|
||||||
"version": "0.10.31",
|
"version": "0.10.31",
|
||||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||||
"integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="
|
"integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/pouchdb-selector-core": {
|
"node_modules/pouchdb-selector-core": {
|
||||||
"version": "8.0.1",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/pouchdb-selector-core/-/pouchdb-selector-core-8.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/pouchdb-selector-core/-/pouchdb-selector-core-8.0.1.tgz",
|
||||||
"integrity": "sha512-dHWsnR+mLGyfVld1vSHJI1xKTwS1xk1G2dggjfXfUrLehI+wysjTUOwiSNytyPzG6DpT+o86wyUpwzPwsDCLBw==",
|
"integrity": "sha512-dHWsnR+mLGyfVld1vSHJI1xKTwS1xk1G2dggjfXfUrLehI+wysjTUOwiSNytyPzG6DpT+o86wyUpwzPwsDCLBw==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pouchdb-collate": "8.0.1",
|
"pouchdb-collate": "8.0.1",
|
||||||
"pouchdb-utils": "8.0.1"
|
"pouchdb-utils": "8.0.1"
|
||||||
@ -3174,6 +3215,7 @@
|
|||||||
"version": "8.0.1",
|
"version": "8.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/pouchdb-utils/-/pouchdb-utils-8.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/pouchdb-utils/-/pouchdb-utils-8.0.1.tgz",
|
||||||
"integrity": "sha512-pWgxdk9EHVWJmjQoEvTe+ZlPXyjcuQ/vgLITN+RjGwcYhoQYUE1M0PksQd2dUP3V8lGS4+wrg9lEM/qSJPYcpw==",
|
"integrity": "sha512-pWgxdk9EHVWJmjQoEvTe+ZlPXyjcuQ/vgLITN+RjGwcYhoQYUE1M0PksQd2dUP3V8lGS4+wrg9lEM/qSJPYcpw==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"clone-buffer": "1.0.0",
|
"clone-buffer": "1.0.0",
|
||||||
"immediate": "3.3.0",
|
"immediate": "3.3.0",
|
||||||
@ -3195,22 +3237,26 @@
|
|||||||
"node_modules/process-nextick-args": {
|
"node_modules/process-nextick-args": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/prr": {
|
"node_modules/prr": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
|
||||||
"integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw=="
|
"integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/psl": {
|
"node_modules/psl": {
|
||||||
"version": "1.9.0",
|
"version": "1.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
|
||||||
"integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag=="
|
"integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/punycode": {
|
"node_modules/punycode": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
|
||||||
"integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
|
"integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
|
||||||
|
"inBundle": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
@ -3218,7 +3264,8 @@
|
|||||||
"node_modules/querystringify": {
|
"node_modules/querystringify": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
|
||||||
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
|
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/randomatic": {
|
"node_modules/randomatic": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
@ -3280,6 +3327,7 @@
|
|||||||
"version": "2.3.8",
|
"version": "2.3.8",
|
||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
|
||||||
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
|
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-util-is": "~1.0.0",
|
"core-util-is": "~1.0.0",
|
||||||
"inherits": "~2.0.3",
|
"inherits": "~2.0.3",
|
||||||
@ -3293,7 +3341,8 @@
|
|||||||
"node_modules/readable-stream/node_modules/safe-buffer": {
|
"node_modules/readable-stream/node_modules/safe-buffer": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/readdirp": {
|
"node_modules/readdirp": {
|
||||||
"version": "2.2.1",
|
"version": "2.2.1",
|
||||||
@ -3694,7 +3743,8 @@
|
|||||||
"node_modules/requires-port": {
|
"node_modules/requires-port": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||||
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
|
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/resolve": {
|
"node_modules/resolve": {
|
||||||
"version": "1.22.8",
|
"version": "1.22.8",
|
||||||
@ -4145,7 +4195,8 @@
|
|||||||
"node_modules/spark-md5": {
|
"node_modules/spark-md5": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz",
|
||||||
"integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw=="
|
"integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/split-string": {
|
"node_modules/split-string": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
@ -4235,6 +4286,7 @@
|
|||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"safe-buffer": "~5.1.0"
|
"safe-buffer": "~5.1.0"
|
||||||
}
|
}
|
||||||
@ -4242,7 +4294,8 @@
|
|||||||
"node_modules/string_decoder/node_modules/safe-buffer": {
|
"node_modules/string_decoder/node_modules/safe-buffer": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/string-width": {
|
"node_modules/string-width": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
@ -4405,6 +4458,7 @@
|
|||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz",
|
||||||
"integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==",
|
"integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"inherits": "^2.0.4",
|
"inherits": "^2.0.4",
|
||||||
"readable-stream": "2 || 3"
|
"readable-stream": "2 || 3"
|
||||||
@ -4466,6 +4520,7 @@
|
|||||||
"version": "4.1.3",
|
"version": "4.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
|
||||||
"integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
|
"integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"psl": "^1.1.33",
|
"psl": "^1.1.33",
|
||||||
"punycode": "^2.1.1",
|
"punycode": "^2.1.1",
|
||||||
@ -4479,7 +4534,8 @@
|
|||||||
"node_modules/tr46": {
|
"node_modules/tr46": {
|
||||||
"version": "0.0.3",
|
"version": "0.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/ts-loader": {
|
"node_modules/ts-loader": {
|
||||||
"version": "9.5.0",
|
"version": "9.5.0",
|
||||||
@ -4655,6 +4711,7 @@
|
|||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
|
||||||
"integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
|
"integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
|
||||||
|
"inBundle": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 4.0.0"
|
"node": ">= 4.0.0"
|
||||||
}
|
}
|
||||||
@ -4766,6 +4823,7 @@
|
|||||||
"version": "1.5.10",
|
"version": "1.5.10",
|
||||||
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
|
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
|
||||||
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
|
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"querystringify": "^2.1.1",
|
"querystringify": "^2.1.1",
|
||||||
"requires-port": "^1.0.0"
|
"requires-port": "^1.0.0"
|
||||||
@ -4783,12 +4841,14 @@
|
|||||||
"node_modules/util-deprecate": {
|
"node_modules/util-deprecate": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/uuid": {
|
"node_modules/uuid": {
|
||||||
"version": "8.3.2",
|
"version": "8.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||||
|
"inBundle": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"uuid": "dist/bin/uuid"
|
"uuid": "dist/bin/uuid"
|
||||||
}
|
}
|
||||||
@ -4802,7 +4862,8 @@
|
|||||||
"node_modules/vuvuzela": {
|
"node_modules/vuvuzela": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/vuvuzela/-/vuvuzela-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/vuvuzela/-/vuvuzela-1.0.3.tgz",
|
||||||
"integrity": "sha512-Tm7jR1xTzBbPW+6y1tknKiEhz04Wf/1iZkcTJjSFcpNko43+dFW6+OOeQe9taJIug3NdfUAjFKgUSyQrIKaDvQ=="
|
"integrity": "sha512-Tm7jR1xTzBbPW+6y1tknKiEhz04Wf/1iZkcTJjSFcpNko43+dFW6+OOeQe9taJIug3NdfUAjFKgUSyQrIKaDvQ==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/watchpack": {
|
"node_modules/watchpack": {
|
||||||
"version": "2.4.0",
|
"version": "2.4.0",
|
||||||
@ -4820,12 +4881,13 @@
|
|||||||
"node_modules/webidl-conversions": {
|
"node_modules/webidl-conversions": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/webpack": {
|
"node_modules/webpack": {
|
||||||
"version": "5.88.2",
|
"version": "5.89.0",
|
||||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz",
|
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz",
|
||||||
"integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==",
|
"integrity": "sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/eslint-scope": "^3.7.3",
|
"@types/eslint-scope": "^3.7.3",
|
||||||
@ -4949,6 +5011,7 @@
|
|||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tr46": "~0.0.3",
|
"tr46": "~0.0.3",
|
||||||
"webidl-conversions": "^3.0.0"
|
"webidl-conversions": "^3.0.0"
|
||||||
@ -4994,6 +5057,7 @@
|
|||||||
"version": "0.4.3",
|
"version": "0.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/write-stream/-/write-stream-0.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/write-stream/-/write-stream-0.4.3.tgz",
|
||||||
"integrity": "sha512-IJrvkhbAnj89W/GAVdVgbnPiVw5Ntg/B4tc/MUCIEwj/g6JIww1DWJyB/yBMT3yw2/TkT6IUZ0+IYef3flEw8A==",
|
"integrity": "sha512-IJrvkhbAnj89W/GAVdVgbnPiVw5Ntg/B4tc/MUCIEwj/g6JIww1DWJyB/yBMT3yw2/TkT6IUZ0+IYef3flEw8A==",
|
||||||
|
"inBundle": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"readable-stream": "~0.0.2"
|
"readable-stream": "~0.0.2"
|
||||||
}
|
}
|
||||||
@ -5001,12 +5065,14 @@
|
|||||||
"node_modules/write-stream/node_modules/readable-stream": {
|
"node_modules/write-stream/node_modules/readable-stream": {
|
||||||
"version": "0.0.4",
|
"version": "0.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-0.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-0.0.4.tgz",
|
||||||
"integrity": "sha512-azrivNydKRYt7zwLV5wWUK7YzKTWs3q87xSmY6DlHapPrCvaT6ZrukvM5erV+yCSSPmZT8zkSdttOHQpWWm9zw=="
|
"integrity": "sha512-azrivNydKRYt7zwLV5wWUK7YzKTWs3q87xSmY6DlHapPrCvaT6ZrukvM5erV+yCSSPmZT8zkSdttOHQpWWm9zw==",
|
||||||
|
"inBundle": true
|
||||||
},
|
},
|
||||||
"node_modules/xtend": {
|
"node_modules/xtend": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
||||||
|
"inBundle": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.4"
|
"node": ">=0.4"
|
||||||
}
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "data-plugin",
|
"name": "@janhq/data-plugin",
|
||||||
"version": "1.0.4",
|
"version": "1.0.0",
|
||||||
"description": "The Data Connector provides easy access to a data API using the PouchDB engine. It offers accessible data management capabilities.",
|
"description": "The Data Connector provides easy access to a data API using the PouchDB engine. It offers accessible data management capabilities.",
|
||||||
"icon": "https://raw.githubusercontent.com/tailwindlabs/heroicons/88e98b0c2b458553fbadccddc2d2f878edc0387b/src/20/solid/circle-stack.svg",
|
"icon": "https://raw.githubusercontent.com/tailwindlabs/heroicons/88e98b0c2b458553fbadccddc2d2f878edc0387b/src/20/solid/circle-stack.svg",
|
||||||
"main": "dist/esm/index.js",
|
"main": "dist/esm/index.js",
|
||||||
@ -12,7 +12,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc --project ./config/tsconfig.esm.json && tsc --project ./config/tsconfig.cjs.json && webpack --config webpack.config.js",
|
"build": "tsc --project ./config/tsconfig.esm.json && tsc --project ./config/tsconfig.cjs.json && webpack --config webpack.config.js",
|
||||||
"postinstall": "rimraf ./data-plugin*.tgz && npm run build",
|
"postinstall": "rimraf ./data-plugin*.tgz && npm run build",
|
||||||
"build:publish": "npm pack && cpx *.tgz ../../pre-install"
|
"build:publish": "npm pack && cpx *.tgz ../../electron/core/pre-install"
|
||||||
},
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
"import": "./dist/esm/index.js",
|
"import": "./dist/esm/index.js",
|
||||||
@ -39,7 +39,7 @@
|
|||||||
"node_modules"
|
"node_modules"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@janhq/plugin-core": "file:../../../../plugin-core",
|
"@janhq/plugin-core": "^0.1.8",
|
||||||
"pouchdb-find": "^8.0.1",
|
"pouchdb-find": "^8.0.1",
|
||||||
"pouchdb-node": "^8.0.1"
|
"pouchdb-node": "^8.0.1"
|
||||||
}
|
}
|
||||||
97
plugins/inference-plugin/index.ts
Normal file
97
plugins/inference-plugin/index.ts
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
import { EventName, InferenceService, NewMessageRequest, PluginService, core, events, store } from "@janhq/plugin-core";
|
||||||
|
|
||||||
|
const PluginName = "@janhq/inference-plugin";
|
||||||
|
const MODULE_PATH = `${PluginName}/dist/module.js`;
|
||||||
|
const inferenceUrl = "http://localhost:3928/llama/chat_completion";
|
||||||
|
|
||||||
|
const initModel = async (product) => core.invokePluginFunc(MODULE_PATH, "initModel", product);
|
||||||
|
|
||||||
|
const stopModel = () => {
|
||||||
|
core.invokePluginFunc(MODULE_PATH, "killSubprocess");
|
||||||
|
};
|
||||||
|
|
||||||
|
async function handleMessageRequest(data: NewMessageRequest) {
|
||||||
|
// TODO: Common collections should be able to access via core functions instead of store
|
||||||
|
const messageHistory =
|
||||||
|
(await store.findMany("messages", { conversationId: data.conversationId }, [{ createdAt: "asc" }])) ?? [];
|
||||||
|
const recentMessages = messageHistory
|
||||||
|
.filter((e) => e.message !== "" && (e.user === "user" || e.user === "assistant"))
|
||||||
|
.slice(-10)
|
||||||
|
.map((message) => {
|
||||||
|
return {
|
||||||
|
content: message.message.trim(),
|
||||||
|
role: message.user === "user" ? "user" : "assistant",
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
...data,
|
||||||
|
message: "",
|
||||||
|
user: "assistant",
|
||||||
|
createdAt: new Date().toISOString(),
|
||||||
|
_id: undefined,
|
||||||
|
};
|
||||||
|
// TODO: Common collections should be able to access via core functions instead of store
|
||||||
|
const id = await store.insertOne("messages", message);
|
||||||
|
|
||||||
|
message._id = id;
|
||||||
|
events.emit(EventName.OnNewMessageResponse, message);
|
||||||
|
|
||||||
|
const response = await fetch(inferenceUrl, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Accept: "text/event-stream",
|
||||||
|
"Access-Control-Allow-Origi": "*",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
messages: recentMessages,
|
||||||
|
stream: true,
|
||||||
|
model: "gpt-3.5-turbo",
|
||||||
|
max_tokens: 500,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
const stream = response.body;
|
||||||
|
|
||||||
|
const decoder = new TextDecoder("utf-8");
|
||||||
|
const reader = stream?.getReader();
|
||||||
|
let answer = "";
|
||||||
|
|
||||||
|
while (true && reader) {
|
||||||
|
const { done, value } = await reader.read();
|
||||||
|
if (done) {
|
||||||
|
console.log("SSE stream closed");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const text = decoder.decode(value);
|
||||||
|
const lines = text.trim().split("\n");
|
||||||
|
for (const line of lines) {
|
||||||
|
if (line.startsWith("data: ") && !line.includes("data: [DONE]")) {
|
||||||
|
const data = JSON.parse(line.replace("data: ", ""));
|
||||||
|
answer += data.choices[0]?.delta?.content ?? "";
|
||||||
|
if (answer.startsWith("assistant: ")) {
|
||||||
|
answer = answer.replace("assistant: ", "");
|
||||||
|
}
|
||||||
|
message.message = answer;
|
||||||
|
events.emit(EventName.OnMessageResponseUpdate, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
message.message = answer.trim();
|
||||||
|
// TODO: Common collections should be able to access via core functions instead of store
|
||||||
|
await store.updateOne("messages", message._id, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
const registerListener = () => {
|
||||||
|
events.on(EventName.OnNewMessageRequest, handleMessageRequest);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onStart = async () => {
|
||||||
|
registerListener();
|
||||||
|
};
|
||||||
|
// Register all the above functions and objects with the relevant extension points
|
||||||
|
export function init({ register }) {
|
||||||
|
register(PluginService.OnStart, PluginName, onStart);
|
||||||
|
register(InferenceService.InitModel, initModel.name, initModel);
|
||||||
|
register(InferenceService.StopModel, stopModel.name, stopModel);
|
||||||
|
}
|
||||||
@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "inference-plugin",
|
"name": "@janhq/inference-plugin",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "inference-plugin",
|
"name": "@janhq/inference-plugin",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundleDependencies": [
|
"bundleDependencies": [
|
||||||
"tcp-port-used",
|
"tcp-port-used",
|
||||||
@ -14,6 +14,7 @@
|
|||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@janhq/plugin-core": "^0.1.8",
|
||||||
"kill-port-process": "^3.2.0",
|
"kill-port-process": "^3.2.0",
|
||||||
"tcp-port-used": "^1.0.2",
|
"tcp-port-used": "^1.0.2",
|
||||||
"ts-loader": "^9.5.0"
|
"ts-loader": "^9.5.0"
|
||||||
@ -37,6 +38,11 @@
|
|||||||
"node": ">=10.0.0"
|
"node": ">=10.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@janhq/plugin-core": {
|
||||||
|
"version": "0.1.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@janhq/plugin-core/-/plugin-core-0.1.8.tgz",
|
||||||
|
"integrity": "sha512-wJe+8ndMQLGLSV36Jt1V3s5lmH+nQw87ol2NMhHuVWXfwf+DAO1GTdTeHfemHWdcB/oUY1HVRvsNh8DvBgbh/w=="
|
||||||
|
},
|
||||||
"node_modules/@jridgewell/gen-mapping": {
|
"node_modules/@jridgewell/gen-mapping": {
|
||||||
"version": "0.3.3",
|
"version": "0.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
|
||||||
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "inference-plugin",
|
"name": "@janhq/inference-plugin",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Inference Plugin, powered by @janhq/nitro, bring a high-performance Llama model inference in pure C++.",
|
"description": "Inference Plugin, powered by @janhq/nitro, bring a high-performance Llama model inference in pure C++.",
|
||||||
"icon": "https://raw.githubusercontent.com/tailwindlabs/heroicons/88e98b0c2b458553fbadccddc2d2f878edc0387b/src/20/solid/command-line.svg",
|
"icon": "https://raw.githubusercontent.com/tailwindlabs/heroicons/88e98b0c2b458553fbadccddc2d2f878edc0387b/src/20/solid/command-line.svg",
|
||||||
@ -12,7 +12,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc -b . && webpack --config webpack.config.js",
|
"build": "tsc -b . && webpack --config webpack.config.js",
|
||||||
"postinstall": "rimraf ./*.tgz && npm run build && rimraf dist/nitro/* && cpx \"nitro/**\" \"dist/nitro\"",
|
"postinstall": "rimraf ./*.tgz && npm run build && rimraf dist/nitro/* && cpx \"nitro/**\" \"dist/nitro\"",
|
||||||
"build:publish": "npm pack && cpx *.tgz ../../pre-install"
|
"build:publish": "npm pack && cpx *.tgz ../../electron/core/pre-install"
|
||||||
},
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
".": "./dist/index.js",
|
".": "./dist/index.js",
|
||||||
@ -25,6 +25,7 @@
|
|||||||
"webpack-cli": "^5.1.4"
|
"webpack-cli": "^5.1.4"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@janhq/plugin-core": "^0.1.8",
|
||||||
"kill-port-process": "^3.2.0",
|
"kill-port-process": "^3.2.0",
|
||||||
"tcp-port-used": "^1.0.2",
|
"tcp-port-used": "^1.0.2",
|
||||||
"ts-loader": "^9.5.0"
|
"ts-loader": "^9.5.0"
|
||||||
13
plugins/inference-plugin/tsconfig.json
Normal file
13
plugins/inference-plugin/tsconfig.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es2016",
|
||||||
|
"module": "ES6",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
|
||||||
|
"outDir": "./dist",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"strict": false,
|
||||||
|
"skipLibCheck": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,7 @@
|
|||||||
import { ModelManagementService, RegisterExtensionPoint, core, store } from "@janhq/plugin-core";
|
import { ModelManagementService, PluginService, RegisterExtensionPoint, core, store } from "@janhq/plugin-core";
|
||||||
const MODULE_PATH = "model-management-plugin/dist/module.js";
|
|
||||||
|
const PluginName = "@janhq/model-management-plugin";
|
||||||
|
const MODULE_PATH = "@janhq/model-management-plugin/dist/module.js";
|
||||||
|
|
||||||
const getDownloadedModels = () => core.invokePluginFunc(MODULE_PATH, "getDownloadedModels");
|
const getDownloadedModels = () => core.invokePluginFunc(MODULE_PATH, "getDownloadedModels");
|
||||||
|
|
||||||
@ -81,7 +83,7 @@ function onStart() {
|
|||||||
|
|
||||||
// Register all the above functions and objects with the relevant extension points
|
// Register all the above functions and objects with the relevant extension points
|
||||||
export function init({ register }: { register: RegisterExtensionPoint }) {
|
export function init({ register }: { register: RegisterExtensionPoint }) {
|
||||||
onStart();
|
register(PluginService.OnStart, PluginName, onStart);
|
||||||
|
|
||||||
register(ModelManagementService.GetDownloadedModels, getDownloadedModels.name, getDownloadedModels);
|
register(ModelManagementService.GetDownloadedModels, getDownloadedModels.name, getDownloadedModels);
|
||||||
register(ModelManagementService.GetAvailableModels, getAvailableModels.name, getAvailableModels);
|
register(ModelManagementService.GetAvailableModels, getAvailableModels.name, getAvailableModels);
|
||||||
@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "model-management-plugin",
|
"name": "@janhq/model-management-plugin",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "model-management-plugin",
|
"name": "@janhq/model-management-plugin",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundleDependencies": [
|
"bundleDependencies": [
|
||||||
"@huggingface/hub"
|
"@huggingface/hub"
|
||||||
@ -14,7 +14,7 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@huggingface/hub": "^0.8.5",
|
"@huggingface/hub": "^0.8.5",
|
||||||
"@janhq/plugin-core": "file:../../../../plugin-core",
|
"@janhq/plugin-core": "^0.1.8",
|
||||||
"ts-loader": "^9.5.0"
|
"ts-loader": "^9.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -24,14 +24,6 @@
|
|||||||
"webpack-cli": "^5.1.4"
|
"webpack-cli": "^5.1.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"../../../../plugin-core": {
|
|
||||||
"name": "@janhq/plugin-core",
|
|
||||||
"version": "0.1.0",
|
|
||||||
"license": "MIT",
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/node": "^12.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@discoveryjs/json-ext": {
|
"node_modules/@discoveryjs/json-ext": {
|
||||||
"version": "0.5.7",
|
"version": "0.5.7",
|
||||||
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
|
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
|
||||||
@ -54,8 +46,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@janhq/plugin-core": {
|
"node_modules/@janhq/plugin-core": {
|
||||||
"resolved": "../../../../plugin-core",
|
"version": "0.1.8",
|
||||||
"link": true
|
"resolved": "https://registry.npmjs.org/@janhq/plugin-core/-/plugin-core-0.1.8.tgz",
|
||||||
|
"integrity": "sha512-wJe+8ndMQLGLSV36Jt1V3s5lmH+nQw87ol2NMhHuVWXfwf+DAO1GTdTeHfemHWdcB/oUY1HVRvsNh8DvBgbh/w=="
|
||||||
},
|
},
|
||||||
"node_modules/@jridgewell/gen-mapping": {
|
"node_modules/@jridgewell/gen-mapping": {
|
||||||
"version": "0.3.3",
|
"version": "0.3.3",
|
||||||
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "model-management-plugin",
|
"name": "@janhq/model-management-plugin",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Model Management Plugin provides model exploration and seamless downloads",
|
"description": "Model Management Plugin provides model exploration and seamless downloads",
|
||||||
"icon": "https://raw.githubusercontent.com/tailwindlabs/heroicons/88e98b0c2b458553fbadccddc2d2f878edc0387b/src/20/solid/queue-list.svg",
|
"icon": "https://raw.githubusercontent.com/tailwindlabs/heroicons/88e98b0c2b458553fbadccddc2d2f878edc0387b/src/20/solid/queue-list.svg",
|
||||||
@ -12,7 +12,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc -b . && webpack --config webpack.config.js",
|
"build": "tsc -b . && webpack --config webpack.config.js",
|
||||||
"postinstall": "rimraf ./*.tgz && npm run build",
|
"postinstall": "rimraf ./*.tgz && npm run build",
|
||||||
"build:publish": "npm pack && cpx *.tgz ../../pre-install"
|
"build:publish": "npm pack && cpx *.tgz ../../electron/core/pre-install"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"cpx": "^1.5.0",
|
"cpx": "^1.5.0",
|
||||||
@ -27,7 +27,7 @@
|
|||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@huggingface/hub": "^0.8.5",
|
"@huggingface/hub": "^0.8.5",
|
||||||
"@janhq/plugin-core": "file:../../../../plugin-core",
|
"@janhq/plugin-core": "^0.1.8",
|
||||||
"ts-loader": "^9.5.0"
|
"ts-loader": "^9.5.0"
|
||||||
},
|
},
|
||||||
"bundledDependencies": [
|
"bundledDependencies": [
|
||||||
@ -1,5 +1,5 @@
|
|||||||
// Provide an async method to manipulate the price provided by the extension point
|
// Provide an async method to manipulate the price provided by the extension point
|
||||||
const PLUGIN_NAME = "monitoring-plugin/dist/module.js";
|
const PLUGIN_NAME = "@janhq/monitoring-plugin/dist/module.js";
|
||||||
|
|
||||||
const getResourcesInfo = () => {
|
const getResourcesInfo = () => {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "monitoring-plugin",
|
"name": "@janhq/monitoring-plugin",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "monitoring-plugin",
|
"name": "@janhq/monitoring-plugin",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundleDependencies": [
|
"bundleDependencies": [
|
||||||
"systeminformation"
|
"systeminformation"
|
||||||
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "monitoring-plugin",
|
"name": "@janhq/monitoring-plugin",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Utilizing systeminformation, it provides essential System and OS information retrieval",
|
"description": "Utilizing systeminformation, it provides essential System and OS information retrieval",
|
||||||
"icon": "https://raw.githubusercontent.com/tailwindlabs/heroicons/88e98b0c2b458553fbadccddc2d2f878edc0387b/src/20/solid/cpu-chip.svg",
|
"icon": "https://raw.githubusercontent.com/tailwindlabs/heroicons/88e98b0c2b458553fbadccddc2d2f878edc0387b/src/20/solid/cpu-chip.svg",
|
||||||
@ -12,7 +12,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "webpack --config webpack.config.js",
|
"build": "webpack --config webpack.config.js",
|
||||||
"postinstall": "rimraf ./*.tgz && npm run build && cpx \"module.js\" \"dist\"",
|
"postinstall": "rimraf ./*.tgz && npm run build && cpx \"module.js\" \"dist\"",
|
||||||
"build:publish": "npm pack && cpx *.tgz ../../pre-install"
|
"build:publish": "npm pack && cpx *.tgz ../../electron/core/pre-install"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
115
plugins/openai-plugin/index.ts
Normal file
115
plugins/openai-plugin/index.ts
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
import {
|
||||||
|
PluginService,
|
||||||
|
EventName,
|
||||||
|
NewMessageRequest,
|
||||||
|
events,
|
||||||
|
store,
|
||||||
|
preferences,
|
||||||
|
RegisterExtensionPoint,
|
||||||
|
} from "@janhq/plugin-core";
|
||||||
|
import { Configuration, OpenAIApi } from "azure-openai";
|
||||||
|
|
||||||
|
const PluginName = "@janhq/openai-plugin";
|
||||||
|
|
||||||
|
const setRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
|
||||||
|
XMLHttpRequest.prototype.setRequestHeader = function newSetRequestHeader(key: string, val: string) {
|
||||||
|
if (key.toLocaleLowerCase() === "user-agent") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setRequestHeader.apply(this, [key, val]);
|
||||||
|
};
|
||||||
|
|
||||||
|
var openai: OpenAIApi | undefined = undefined;
|
||||||
|
|
||||||
|
const setup = async () => {
|
||||||
|
const apiKey: string = (await preferences.get(PluginName, "apiKey")) ?? "";
|
||||||
|
const endpoint: string = (await preferences.get(PluginName, "endpoint")) ?? "";
|
||||||
|
const deploymentName: string = (await preferences.get(PluginName, "deploymentName")) ?? "";
|
||||||
|
try {
|
||||||
|
openai = new OpenAIApi(
|
||||||
|
new Configuration({
|
||||||
|
azure: {
|
||||||
|
apiKey, //Your API key goes here
|
||||||
|
endpoint, //Your endpoint goes here. It is like: "https://endpointname.openai.azure.com/"
|
||||||
|
deploymentName, //Your deployment name goes here. It is like "chatgpt"
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
openai = undefined;
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async function onStart() {
|
||||||
|
setup();
|
||||||
|
registerListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleMessageRequest(data: NewMessageRequest) {
|
||||||
|
if (!openai) {
|
||||||
|
const message = {
|
||||||
|
...data,
|
||||||
|
message: "Your API key is not set. Please set it in the plugin preferences.",
|
||||||
|
user: "GPT-3",
|
||||||
|
avatar: "https://static-assets.jan.ai/openai-icon.jpg",
|
||||||
|
createdAt: new Date().toISOString(),
|
||||||
|
_id: undefined,
|
||||||
|
};
|
||||||
|
const id = await store.insertOne("messages", message);
|
||||||
|
message._id = id;
|
||||||
|
events.emit(EventName.OnNewMessageResponse, message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
...data,
|
||||||
|
message: "",
|
||||||
|
user: "GPT-3",
|
||||||
|
avatar: "https://static-assets.jan.ai/openai-icon.jpg",
|
||||||
|
createdAt: new Date().toISOString(),
|
||||||
|
_id: undefined,
|
||||||
|
};
|
||||||
|
const id = await store.insertOne("messages", message);
|
||||||
|
|
||||||
|
message._id = id;
|
||||||
|
events.emit(EventName.OnNewMessageResponse, message);
|
||||||
|
const response = await openai.createChatCompletion({
|
||||||
|
messages: [{ role: "user", content: data.message }],
|
||||||
|
model: "gpt-3.5-turbo",
|
||||||
|
});
|
||||||
|
message.message = response.data.choices[0].message.content;
|
||||||
|
events.emit(EventName.OnMessageResponseUpdate, message);
|
||||||
|
await store.updateOne("messages", message._id, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
const registerListener = () => {
|
||||||
|
events.on(EventName.OnNewMessageRequest, handleMessageRequest);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onPreferencesUpdate = () => {
|
||||||
|
setup();
|
||||||
|
};
|
||||||
|
// Register all the above functions and objects with the relevant extension points
|
||||||
|
export function init({ register }: { register: RegisterExtensionPoint }) {
|
||||||
|
register(PluginService.OnStart, PluginName, onStart);
|
||||||
|
register(PluginService.OnPreferencesUpdate, PluginName, onPreferencesUpdate);
|
||||||
|
|
||||||
|
preferences.registerPreferences<string>(register, PluginName, "apiKey", "API Key", "Azure Project API Key", "");
|
||||||
|
preferences.registerPreferences<string>(
|
||||||
|
register,
|
||||||
|
PluginName,
|
||||||
|
"endpoint",
|
||||||
|
"API Endpoint",
|
||||||
|
"Azure Deployment Endpoint API",
|
||||||
|
""
|
||||||
|
);
|
||||||
|
preferences.registerPreferences<string>(
|
||||||
|
register,
|
||||||
|
PluginName,
|
||||||
|
"deploymentName",
|
||||||
|
"Deployment Name",
|
||||||
|
"The deployment name you chose when you deployed the model",
|
||||||
|
""
|
||||||
|
);
|
||||||
|
}
|
||||||
3708
plugins/openai-plugin/package-lock.json
generated
Normal file
3708
plugins/openai-plugin/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
46
plugins/openai-plugin/package.json
Normal file
46
plugins/openai-plugin/package.json
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
{
|
||||||
|
"name": "@janhq/azure-openai-plugin",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Inference plugin for Azure OpenAI",
|
||||||
|
"icon": "https://static-assets.jan.ai/openai-icon.jpg",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"author": "Jan",
|
||||||
|
"license": "MIT",
|
||||||
|
"activationPoints": [
|
||||||
|
"init"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc -b . && webpack --config webpack.config.js",
|
||||||
|
"postinstall": "rimraf ./*.tgz && npm run build && rimraf dist/nitro/* && cpx \"nitro/**\" \"dist/nitro\"",
|
||||||
|
"build:publish": "npm pack && cpx *.tgz ../../electron/core/pre-install"
|
||||||
|
},
|
||||||
|
"exports": {
|
||||||
|
".": "./dist/index.js",
|
||||||
|
"./main": "./dist/module.js"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"cpx": "^1.5.0",
|
||||||
|
"rimraf": "^3.0.2",
|
||||||
|
"webpack": "^5.88.2",
|
||||||
|
"webpack-cli": "^5.1.4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@janhq/plugin-core": "^0.1.8",
|
||||||
|
"azure-openai": "^0.9.4",
|
||||||
|
"kill-port-process": "^3.2.0",
|
||||||
|
"tcp-port-used": "^1.0.2",
|
||||||
|
"ts-loader": "^9.5.0"
|
||||||
|
},
|
||||||
|
"bundledDependencies": [
|
||||||
|
"tcp-port-used",
|
||||||
|
"kill-port-process"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"dist/*",
|
||||||
|
"package.json",
|
||||||
|
"README.md"
|
||||||
|
]
|
||||||
|
}
|
||||||
13
plugins/openai-plugin/tsconfig.json
Normal file
13
plugins/openai-plugin/tsconfig.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es2016",
|
||||||
|
"module": "ES6",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
|
||||||
|
"outDir": "./dist",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"strict": false,
|
||||||
|
"skipLibCheck": true
|
||||||
|
}
|
||||||
|
}
|
||||||
25
plugins/openai-plugin/webpack.config.js
Normal file
25
plugins/openai-plugin/webpack.config.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
experiments: { outputModule: true },
|
||||||
|
entry: "./index.ts", // Adjust the entry point to match your project's main file
|
||||||
|
mode: "production",
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.tsx?$/,
|
||||||
|
use: "ts-loader",
|
||||||
|
exclude: /node_modules/,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
filename: "index.js", // Adjust the output file name as needed
|
||||||
|
path: path.resolve(__dirname, "dist"),
|
||||||
|
library: { type: "module" }, // Specify ESM output format
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
extensions: [".ts", ".js"],
|
||||||
|
},
|
||||||
|
// Add loaders and other configuration as needed for your project
|
||||||
|
};
|
||||||
@ -6,21 +6,22 @@ import {
|
|||||||
extensionPoints,
|
extensionPoints,
|
||||||
activationPoints,
|
activationPoints,
|
||||||
} from "@/../../electron/core/plugin-manager/execution/index";
|
} from "@/../../electron/core/plugin-manager/execution/index";
|
||||||
import {
|
import { ChartPieIcon, CommandLineIcon, PlayIcon } from "@heroicons/react/24/outline";
|
||||||
ChartPieIcon,
|
|
||||||
CommandLineIcon,
|
|
||||||
PlayIcon,
|
|
||||||
} from "@heroicons/react/24/outline";
|
|
||||||
|
|
||||||
import { MagnifyingGlassIcon } from "@heroicons/react/20/solid";
|
import { MagnifyingGlassIcon } from "@heroicons/react/20/solid";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
|
import { PluginService, preferences } from "@janhq/plugin-core";
|
||||||
|
import { execute } from "../../../electron/core/plugin-manager/execution/extension-manager";
|
||||||
|
|
||||||
/* eslint-disable @next/next/no-sync-scripts */
|
|
||||||
export const Preferences = () => {
|
export const Preferences = () => {
|
||||||
const [search, setSearch] = useState<string>("");
|
const [search, setSearch] = useState<string>("");
|
||||||
const [activePlugins, setActivePlugins] = useState<any[]>([]);
|
const [activePlugins, setActivePlugins] = useState<any[]>([]);
|
||||||
|
const [preferenceItems, setPreferenceItems] = useState<any[]>([]);
|
||||||
|
const [preferenceValues, setPreferenceValues] = useState<any[]>([]);
|
||||||
const [isTestAvailable, setIsTestAvailable] = useState(false);
|
const [isTestAvailable, setIsTestAvailable] = useState(false);
|
||||||
const [fileName, setFileName] = useState("");
|
const [fileName, setFileName] = useState("");
|
||||||
|
const experimentRef = useRef(null);
|
||||||
|
const preferenceRef = useRef(null);
|
||||||
|
|
||||||
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const file = event.target.files?.[0];
|
const file = event.target.files?.[0];
|
||||||
@ -31,7 +32,6 @@ export const Preferences = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const preferenceRef = useRef(null);
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function setupPE() {
|
async function setupPE() {
|
||||||
// Enable activation point management
|
// Enable activation point management
|
||||||
@ -54,19 +54,22 @@ export const Preferences = () => {
|
|||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
await activationPoints.trigger("init");
|
await activationPoints.trigger("init");
|
||||||
if (extensionPoints.get("experimentComponent")) {
|
if (extensionPoints.get("experimentComponent")) {
|
||||||
const components = await Promise.all(
|
const components = await Promise.all(extensionPoints.execute("experimentComponent"));
|
||||||
extensionPoints.execute("experimentComponent")
|
|
||||||
);
|
|
||||||
if (components.length > 0) {
|
if (components.length > 0) {
|
||||||
setIsTestAvailable(true);
|
setIsTestAvailable(true);
|
||||||
}
|
}
|
||||||
components.forEach((e) => {
|
components.forEach((e) => {
|
||||||
if (preferenceRef.current) {
|
if (experimentRef.current) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
preferenceRef.current.appendChild(e);
|
experimentRef.current.appendChild(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (extensionPoints.get("PluginPreferences")) {
|
||||||
|
const data = await Promise.all(extensionPoints.execute("PluginPreferences"));
|
||||||
|
setPreferenceItems(Array.isArray(data) ? data : []);
|
||||||
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
};
|
};
|
||||||
setupPE().then(() => activePlugins());
|
setupPE().then(() => activePlugins());
|
||||||
@ -86,17 +89,9 @@ export const Preferences = () => {
|
|||||||
|
|
||||||
// Uninstall a plugin on clicking uninstall
|
// Uninstall a plugin on clicking uninstall
|
||||||
const uninstall = async (name: string) => {
|
const uninstall = async (name: string) => {
|
||||||
//@ts-ignore
|
|
||||||
|
|
||||||
// Send the filename of the to be uninstalled plugin
|
// Send the filename of the to be uninstalled plugin
|
||||||
// to the main process for removal
|
// to the main process for removal
|
||||||
//@ts-ignore
|
|
||||||
const res = await plugins.uninstall([name]);
|
const res = await plugins.uninstall([name]);
|
||||||
console.log(
|
|
||||||
res
|
|
||||||
? "Plugin successfully uninstalled"
|
|
||||||
: "Plugin could not be uninstalled"
|
|
||||||
);
|
|
||||||
if (res) window.electronAPI.relaunch();
|
if (res) window.electronAPI.relaunch();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -110,6 +105,26 @@ export const Preferences = () => {
|
|||||||
// plugins.update(active.map((plg) => plg.name));
|
// plugins.update(active.map((plg) => plg.name));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let timeout: any | undefined = undefined;
|
||||||
|
function notifyPreferenceUpdate() {
|
||||||
|
if (timeout) {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
}
|
||||||
|
timeout = setTimeout(() => execute(PluginService.OnPreferencesUpdate), 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (preferenceItems) {
|
||||||
|
Promise.all(
|
||||||
|
preferenceItems.map((e) =>
|
||||||
|
preferences.get(e.pluginName, e.preferenceKey).then((k) => ({ key: e.preferenceKey, value: k }))
|
||||||
|
)
|
||||||
|
).then((data) => {
|
||||||
|
setPreferenceValues(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [preferenceItems]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full h-screen overflow-scroll">
|
<div className="w-full h-screen overflow-scroll">
|
||||||
<div className="sticky top-0 z-40 flex h-16 shrink-0 items-center gap-x-4 border-b border-gray-200 bg-white shadow-sm sm:gap-x-6 sm:px-6 px-8">
|
<div className="sticky top-0 z-40 flex h-16 shrink-0 items-center gap-x-4 border-b border-gray-200 bg-white shadow-sm sm:gap-x-6 sm:px-6 px-8">
|
||||||
@ -152,12 +167,9 @@ export const Preferences = () => {
|
|||||||
{!fileName ? (
|
{!fileName ? (
|
||||||
<div className="flex flex-col items-center justify-center pt-5 pb-6">
|
<div className="flex flex-col items-center justify-center pt-5 pb-6">
|
||||||
<p className="mb-2 text-sm text-gray-500 dark:text-gray-400">
|
<p className="mb-2 text-sm text-gray-500 dark:text-gray-400">
|
||||||
<span className="font-semibold">Click to upload</span>{" "}
|
<span className="font-semibold">Click to upload</span> or drag and drop
|
||||||
or drag and drop
|
|
||||||
</p>
|
|
||||||
<p className="text-xs text-gray-500 dark:text-gray-400">
|
|
||||||
TGZ (MAX 50MB)
|
|
||||||
</p>
|
</p>
|
||||||
|
<p className="text-xs text-gray-500 dark:text-gray-400">TGZ (MAX 50MB)</p>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>{fileName}</>
|
<>{fileName}</>
|
||||||
@ -177,9 +189,7 @@ export const Preferences = () => {
|
|||||||
type="submit"
|
type="submit"
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"rounded-md px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600",
|
"rounded-md px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600",
|
||||||
fileName
|
fileName ? "bg-blue-500 hover:bg-blue-300" : "bg-gray-500"
|
||||||
? "bg-blue-500 hover:bg-blue-300"
|
|
||||||
: "bg-gray-500"
|
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
Install Plugin
|
Install Plugin
|
||||||
@ -205,11 +215,7 @@ export const Preferences = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-2 items-stretch gap-4">
|
<div className="grid grid-cols-2 items-stretch gap-4">
|
||||||
{activePlugins
|
{activePlugins
|
||||||
.filter(
|
.filter((e) => search.trim() === "" || e.name.toLowerCase().includes(search.toLowerCase()))
|
||||||
(e) =>
|
|
||||||
search.trim() === "" ||
|
|
||||||
e.name.toLowerCase().includes(search.toLowerCase())
|
|
||||||
)
|
|
||||||
.map((e) => (
|
.map((e) => (
|
||||||
<div
|
<div
|
||||||
key={e.name}
|
key={e.name}
|
||||||
@ -218,19 +224,13 @@ export const Preferences = () => {
|
|||||||
>
|
>
|
||||||
<div className="flex flex-row space-x-2 items-center">
|
<div className="flex flex-row space-x-2 items-center">
|
||||||
<span className="relative inline-block mt-1">
|
<span className="relative inline-block mt-1">
|
||||||
<img
|
<img className="h-14 w-14 rounded-md" src={e.icon ?? "icons/app_icon.svg"} alt="" />
|
||||||
className="h-14 w-14 rounded-md"
|
|
||||||
src={e.icon ?? "icons/app_icon.svg"}
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
</span>
|
</span>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<p className="text-xl font-bold tracking-tight text-gray-900 dark:text-white capitalize">
|
<p className="text-xl font-bold tracking-tight text-gray-900 dark:text-white capitalize">
|
||||||
{e.name.replaceAll("-", " ")}
|
{e.name.replaceAll("-", " ")}
|
||||||
</p>
|
</p>
|
||||||
<p className="font-normal text-gray-700 dark:text-gray-400">
|
<p className="font-normal text-gray-700 dark:text-gray-400">Version: {e.version}</p>
|
||||||
Version: {e.version}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -266,8 +266,34 @@ export const Preferences = () => {
|
|||||||
Test Plugins
|
Test Plugins
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="h-full w-full" ref={preferenceRef}></div>
|
<div className="h-full w-full" ref={experimentRef}></div>
|
||||||
{/* Content */}
|
|
||||||
|
<div className="flex flex-row items-center my-4">
|
||||||
|
<PlayIcon width={30} />
|
||||||
|
Preferences
|
||||||
|
</div>
|
||||||
|
<div className="h-full w-full flex flex-col" ref={preferenceRef}>
|
||||||
|
{preferenceItems?.map((e) => (
|
||||||
|
<div key={e.preferenceKey} className="flex flex-col mb-4">
|
||||||
|
<div>
|
||||||
|
<span className="text-[16px] text-gray-600">Setting:</span>{" "}
|
||||||
|
<span className="text-[16px] text-gray-900">{e.preferenceName}</span>
|
||||||
|
</div>
|
||||||
|
<span className="text-[14px] text-gray-400">{e.preferenceDescription}</span>
|
||||||
|
<div className="flex flex-row space-x-4 items-center mt-2">
|
||||||
|
<input
|
||||||
|
className="text-gray-500 w-1/3 rounded-sm border-gray-300 border-[1px] h-8"
|
||||||
|
defaultValue={preferenceValues.filter((v) => v.key === e.preferenceKey)[0]?.value}
|
||||||
|
onChange={(event) => {
|
||||||
|
preferences
|
||||||
|
.set(e.pluginName, e.preferenceKey, event.target.value)
|
||||||
|
.then(() => notifyPreferenceUpdate());
|
||||||
|
}}
|
||||||
|
></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
34
web/app/_helpers/EventHandler.tsx
Normal file
34
web/app/_helpers/EventHandler.tsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { addNewMessageAtom, updateMessageAtom } from "@/_helpers/atoms/ChatMessage.atom";
|
||||||
|
import { toChatMessage } from "@/_models/ChatMessage";
|
||||||
|
import { events, EventName, NewMessageResponse } from "@janhq/plugin-core";
|
||||||
|
import { useSetAtom } from "jotai";
|
||||||
|
import { ReactNode, useEffect } from "react";
|
||||||
|
|
||||||
|
export default function EventHandler({ children }: { children: ReactNode }) {
|
||||||
|
const addNewMessage = useSetAtom(addNewMessageAtom);
|
||||||
|
const updateMessage = useSetAtom(updateMessageAtom);
|
||||||
|
|
||||||
|
function handleNewMessageResponse(message: NewMessageResponse) {
|
||||||
|
const newResponse = toChatMessage(message);
|
||||||
|
addNewMessage(newResponse);
|
||||||
|
}
|
||||||
|
async function handleMessageResponseUpdate(messageResponse: NewMessageResponse) {
|
||||||
|
if (messageResponse.conversationId && messageResponse._id && messageResponse.message)
|
||||||
|
updateMessage(messageResponse._id, messageResponse.conversationId, messageResponse.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (window.corePlugin.events) {
|
||||||
|
events.on(EventName.OnNewMessageResponse, handleNewMessageResponse);
|
||||||
|
events.on(EventName.OnMessageResponseUpdate, handleMessageResponseUpdate);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
events.off(EventName.OnNewMessageResponse, handleNewMessageResponse);
|
||||||
|
events.off(EventName.OnMessageResponseUpdate, handleMessageResponseUpdate);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
return <> {children}</>;
|
||||||
|
}
|
||||||
@ -6,12 +6,10 @@ import { appDownloadProgress } from "./JotaiWrapper";
|
|||||||
import { DownloadState } from "@/_models/DownloadState";
|
import { DownloadState } from "@/_models/DownloadState";
|
||||||
import { executeSerial } from "../../../electron/core/plugin-manager/execution/extension-manager";
|
import { executeSerial } from "../../../electron/core/plugin-manager/execution/extension-manager";
|
||||||
import { ModelManagementService } from "@janhq/plugin-core";
|
import { ModelManagementService } from "@janhq/plugin-core";
|
||||||
import {
|
import { setDownloadStateAtom, setDownloadStateSuccessAtom } from "./atoms/DownloadState.atom";
|
||||||
setDownloadStateAtom,
|
|
||||||
setDownloadStateSuccessAtom,
|
|
||||||
} from "./atoms/DownloadState.atom";
|
|
||||||
import { getDownloadedModels } from "@/_hooks/useGetDownloadedModels";
|
import { getDownloadedModels } from "@/_hooks/useGetDownloadedModels";
|
||||||
import { downloadedModelAtom } from "./atoms/DownloadedModel.atom";
|
import { downloadedModelAtom } from "./atoms/DownloadedModel.atom";
|
||||||
|
import EventHandler from "./EventHandler";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
@ -25,57 +23,46 @@ export default function EventListenerWrapper({ children }: Props) {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (window && window.electronAPI) {
|
if (window && window.electronAPI) {
|
||||||
window.electronAPI.onFileDownloadUpdate(
|
window.electronAPI.onFileDownloadUpdate((_event: string, state: DownloadState | undefined) => {
|
||||||
(_event: string, state: DownloadState | undefined) => {
|
if (!state) return;
|
||||||
if (!state) return;
|
setDownloadState(state);
|
||||||
setDownloadState(state);
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
window.electronAPI.onFileDownloadError(
|
window.electronAPI.onFileDownloadError((_event: string, callback: any) => {
|
||||||
(_event: string, callback: any) => {
|
console.log("Download error", callback);
|
||||||
console.log("Download error", callback);
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
window.electronAPI.onFileDownloadSuccess(
|
window.electronAPI.onFileDownloadSuccess((_event: string, callback: any) => {
|
||||||
(_event: string, callback: any) => {
|
if (callback && callback.fileName) {
|
||||||
if (callback && callback.fileName) {
|
setDownloadStateSuccess(callback.fileName);
|
||||||
setDownloadStateSuccess(callback.fileName);
|
|
||||||
|
|
||||||
executeSerial(
|
executeSerial(ModelManagementService.UpdateFinishedDownloadAt, callback.fileName).then(() => {
|
||||||
ModelManagementService.UpdateFinishedDownloadAt,
|
getDownloadedModels().then((models) => {
|
||||||
callback.fileName
|
setDownloadedModels(models);
|
||||||
).then(() => {
|
|
||||||
getDownloadedModels().then((models) => {
|
|
||||||
setDownloadedModels(models);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
);
|
});
|
||||||
|
|
||||||
window.electronAPI.onAppUpdateDownloadUpdate(
|
window.electronAPI.onAppUpdateDownloadUpdate((_event: string, progress: any) => {
|
||||||
(_event: string, progress: any) => {
|
setProgress(progress.percent);
|
||||||
setProgress(progress.percent);
|
console.log("app update progress:", progress.percent);
|
||||||
console.log("app update progress:", progress.percent);
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
window.electronAPI.onAppUpdateDownloadError(
|
window.electronAPI.onAppUpdateDownloadError((_event: string, callback: any) => {
|
||||||
(_event: string, callback: any) => {
|
console.log("Download error", callback);
|
||||||
console.log("Download error", callback);
|
setProgress(-1);
|
||||||
setProgress(-1);
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
window.electronAPI.onAppUpdateDownloadSuccess(
|
window.electronAPI.onAppUpdateDownloadSuccess((_event: string, callback: any) => {
|
||||||
(_event: string, callback: any) => {
|
setProgress(-1);
|
||||||
setProgress(-1);
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return <div id="eventlistener">{children}</div>;
|
return (
|
||||||
|
<div id="eventlistener">
|
||||||
|
<EventHandler>{children}</EventHandler>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,28 +31,18 @@ const useChatMessages = (offset = 0) => {
|
|||||||
if (!hasMore) return;
|
if (!hasMore) return;
|
||||||
|
|
||||||
const getMessages = async () => {
|
const getMessages = async () => {
|
||||||
executeSerial(
|
executeSerial(DataService.GetConversationMessages, currentConvo._id).then((data: any) => {
|
||||||
DataService.GetConversationMessages,
|
|
||||||
currentConvo._id
|
|
||||||
).then((data: any) => {
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
parseMessages(data ?? []).then((newMessages) => {
|
const newMessages = parseMessages(data ?? []);
|
||||||
addOldChatMessages(newMessages);
|
addOldChatMessages(newMessages);
|
||||||
updateConvoHasMore(currentConvo._id ?? "", false);
|
updateConvoHasMore(currentConvo._id ?? "", false);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
getMessages();
|
getMessages();
|
||||||
}, [
|
}, [offset, currentConvo?._id, convoStates, addOldChatMessages, updateConvoHasMore]);
|
||||||
offset,
|
|
||||||
currentConvo?._id,
|
|
||||||
convoStates,
|
|
||||||
addOldChatMessages,
|
|
||||||
updateConvoHasMore,
|
|
||||||
]);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
loading: loading,
|
loading: loading,
|
||||||
@ -61,10 +51,10 @@ const useChatMessages = (offset = 0) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
async function parseMessages(messages: RawMessage[]): Promise<ChatMessage[]> {
|
function parseMessages(messages: RawMessage[]): ChatMessage[] {
|
||||||
const newMessages: ChatMessage[] = [];
|
const newMessages: ChatMessage[] = [];
|
||||||
for (const m of messages) {
|
for (const m of messages) {
|
||||||
const chatMessage = await toChatMessage(m);
|
const chatMessage = toChatMessage(m);
|
||||||
newMessages.push(chatMessage);
|
newMessages.push(chatMessage);
|
||||||
}
|
}
|
||||||
return newMessages;
|
return newMessages;
|
||||||
|
|||||||
@ -1,51 +1,19 @@
|
|||||||
import { currentPromptAtom } from "@/_helpers/JotaiWrapper";
|
import { currentPromptAtom } from "@/_helpers/JotaiWrapper";
|
||||||
import { useAtom, useAtomValue, useSetAtom } from "jotai";
|
import { useAtom, useAtomValue, useSetAtom } from "jotai";
|
||||||
import { selectAtom } from "jotai/utils";
|
import { DataService, EventName, events } from "@janhq/plugin-core";
|
||||||
import { DataService, InferenceService } from "@janhq/plugin-core";
|
import { RawMessage, toChatMessage } from "@/_models/ChatMessage";
|
||||||
import {
|
|
||||||
ChatMessage,
|
|
||||||
MessageSenderType,
|
|
||||||
RawMessage,
|
|
||||||
toChatMessage,
|
|
||||||
} from "@/_models/ChatMessage";
|
|
||||||
import { executeSerial } from "@/_services/pluginService";
|
import { executeSerial } from "@/_services/pluginService";
|
||||||
import { useCallback } from "react";
|
import { addNewMessageAtom } from "@/_helpers/atoms/ChatMessage.atom";
|
||||||
import {
|
import { currentConversationAtom } from "@/_helpers/atoms/Conversation.atom";
|
||||||
addNewMessageAtom,
|
|
||||||
updateMessageAtom,
|
|
||||||
chatMessages,
|
|
||||||
currentChatMessagesAtom,
|
|
||||||
} from "@/_helpers/atoms/ChatMessage.atom";
|
|
||||||
import {
|
|
||||||
currentConversationAtom,
|
|
||||||
getActiveConvoIdAtom,
|
|
||||||
updateConversationAtom,
|
|
||||||
updateConversationWaitingForResponseAtom,
|
|
||||||
} from "@/_helpers/atoms/Conversation.atom";
|
|
||||||
import { Conversation } from "@/_models/Conversation";
|
|
||||||
|
|
||||||
export default function useSendChatMessage() {
|
export default function useSendChatMessage() {
|
||||||
const currentConvo = useAtomValue(currentConversationAtom);
|
const currentConvo = useAtomValue(currentConversationAtom);
|
||||||
const updateConversation = useSetAtom(updateConversationAtom);
|
|
||||||
const addNewMessage = useSetAtom(addNewMessageAtom);
|
const addNewMessage = useSetAtom(addNewMessageAtom);
|
||||||
const updateMessage = useSetAtom(updateMessageAtom);
|
|
||||||
const activeConversationId = useAtomValue(getActiveConvoIdAtom) ?? "";
|
|
||||||
const updateConvWaiting = useSetAtom(
|
|
||||||
updateConversationWaitingForResponseAtom
|
|
||||||
);
|
|
||||||
|
|
||||||
const chatMessagesHistory = useAtomValue(
|
|
||||||
selectAtom(
|
|
||||||
chatMessages,
|
|
||||||
useCallback((v) => v[activeConversationId], [activeConversationId])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
const [currentPrompt, setCurrentPrompt] = useAtom(currentPromptAtom);
|
const [currentPrompt, setCurrentPrompt] = useAtom(currentPromptAtom);
|
||||||
|
|
||||||
const sendChatMessage = async () => {
|
const sendChatMessage = async () => {
|
||||||
setCurrentPrompt("");
|
setCurrentPrompt("");
|
||||||
const conversationId = activeConversationId;
|
|
||||||
updateConvWaiting(conversationId, true);
|
|
||||||
const prompt = currentPrompt.trim();
|
const prompt = currentPrompt.trim();
|
||||||
const newMessage: RawMessage = {
|
const newMessage: RawMessage = {
|
||||||
conversationId: currentConvo?._id,
|
conversationId: currentConvo?._id,
|
||||||
@ -56,188 +24,9 @@ export default function useSendChatMessage() {
|
|||||||
const id = await executeSerial(DataService.CreateMessage, newMessage);
|
const id = await executeSerial(DataService.CreateMessage, newMessage);
|
||||||
newMessage._id = id;
|
newMessage._id = id;
|
||||||
|
|
||||||
const newChatMessage = await toChatMessage(newMessage);
|
|
||||||
addNewMessage(newChatMessage);
|
|
||||||
const messageHistory = chatMessagesHistory ?? [];
|
|
||||||
const recentMessages = [
|
|
||||||
...messageHistory.sort((a, b) => parseInt(a.id) - parseInt(b.id)),
|
|
||||||
newChatMessage,
|
|
||||||
]
|
|
||||||
.slice(-10)
|
|
||||||
.map((message) => {
|
|
||||||
return {
|
|
||||||
content: message.text,
|
|
||||||
role:
|
|
||||||
message.messageSenderType === MessageSenderType.User
|
|
||||||
? "user"
|
|
||||||
: "assistant",
|
|
||||||
};
|
|
||||||
});
|
|
||||||
const url = await executeSerial(InferenceService.InferenceUrl);
|
|
||||||
const response = await fetch(url, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Accept: "text/event-stream",
|
|
||||||
"Access-Control-Allow-Origi": "*",
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
messages: recentMessages,
|
|
||||||
stream: true,
|
|
||||||
model: "gpt-3.5-turbo",
|
|
||||||
max_tokens: 500,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
const stream = response.body;
|
|
||||||
|
|
||||||
const decoder = new TextDecoder("utf-8");
|
|
||||||
const reader = stream?.getReader();
|
|
||||||
let answer = "";
|
|
||||||
|
|
||||||
// Cache received response
|
|
||||||
const newResponse: RawMessage = {
|
|
||||||
conversationId: currentConvo?._id,
|
|
||||||
message: answer,
|
|
||||||
user: "assistant",
|
|
||||||
createdAt: new Date().toISOString(),
|
|
||||||
};
|
|
||||||
const respId = await executeSerial(DataService.CreateMessage, newResponse);
|
|
||||||
newResponse._id = respId;
|
|
||||||
const responseChatMessage = toChatMessage(newResponse);
|
|
||||||
addNewMessage(responseChatMessage);
|
|
||||||
|
|
||||||
while (true && reader) {
|
|
||||||
const { done, value } = await reader.read();
|
|
||||||
if (done) {
|
|
||||||
console.log("SSE stream closed");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
const text = decoder.decode(value);
|
|
||||||
const lines = text.trim().split("\n");
|
|
||||||
for (const line of lines) {
|
|
||||||
if (line.startsWith("data: ") && !line.includes("data: [DONE]")) {
|
|
||||||
updateConvWaiting(conversationId, false);
|
|
||||||
const data = JSON.parse(line.replace("data: ", ""));
|
|
||||||
answer += data.choices[0]?.delta?.content ?? "";
|
|
||||||
if (answer.startsWith("assistant: ")) {
|
|
||||||
answer = answer.replace("assistant: ", "");
|
|
||||||
}
|
|
||||||
updateMessage(
|
|
||||||
responseChatMessage.id,
|
|
||||||
responseChatMessage.conversationId,
|
|
||||||
answer
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
updateMessage(
|
|
||||||
responseChatMessage.id,
|
|
||||||
responseChatMessage.conversationId,
|
|
||||||
answer.trimEnd()
|
|
||||||
);
|
|
||||||
await executeSerial(DataService.UpdateMessage, {
|
|
||||||
...newResponse,
|
|
||||||
message: answer.trimEnd(),
|
|
||||||
updatedAt: new Date()
|
|
||||||
.toISOString()
|
|
||||||
.replace("T", " ")
|
|
||||||
.replace(/\.\d+Z$/, ""),
|
|
||||||
});
|
|
||||||
|
|
||||||
const updatedConvo: Conversation = {
|
|
||||||
...currentConvo,
|
|
||||||
lastMessage: answer.trim(),
|
|
||||||
updatedAt: new Date().toISOString(),
|
|
||||||
};
|
|
||||||
|
|
||||||
await executeSerial(DataService.UpdateConversation, updatedConvo);
|
|
||||||
updateConversation(updatedConvo);
|
|
||||||
updateConvWaiting(conversationId, false);
|
|
||||||
|
|
||||||
newResponse.message = answer.trim();
|
|
||||||
const messages: RawMessage[] = [newMessage, newResponse];
|
|
||||||
|
|
||||||
inferConvoSummary(updatedConvo, messages);
|
|
||||||
};
|
|
||||||
|
|
||||||
const inferConvoSummary = async (
|
|
||||||
convo: Conversation,
|
|
||||||
lastMessages: RawMessage[]
|
|
||||||
) => {
|
|
||||||
if (convo.summary) return;
|
|
||||||
const newMessage: RawMessage = {
|
|
||||||
conversationId: currentConvo?._id,
|
|
||||||
message: "summary this conversation in 5 words",
|
|
||||||
user: "user",
|
|
||||||
createdAt: new Date().toISOString(),
|
|
||||||
};
|
|
||||||
const messageHistory = lastMessages.map((m) => toChatMessage(m));
|
|
||||||
const newChatMessage = toChatMessage(newMessage);
|
const newChatMessage = toChatMessage(newMessage);
|
||||||
|
addNewMessage(newChatMessage);
|
||||||
const recentMessages = [...messageHistory, newChatMessage]
|
events.emit(EventName.OnNewMessageRequest, newMessage);
|
||||||
.slice(-10)
|
|
||||||
.map((message) => ({
|
|
||||||
content: message.text,
|
|
||||||
role: message.messageSenderType,
|
|
||||||
}));
|
|
||||||
|
|
||||||
console.debug(`Sending ${JSON.stringify(recentMessages)}`);
|
|
||||||
const url = await executeSerial(InferenceService.InferenceUrl);
|
|
||||||
const response = await fetch(url, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Accept: "text/event-stream",
|
|
||||||
"Access-Control-Allow-Origi": "*",
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
messages: recentMessages,
|
|
||||||
stream: true,
|
|
||||||
model: "gpt-3.5-turbo",
|
|
||||||
max_tokens: 500,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
const stream = response.body;
|
|
||||||
|
|
||||||
const decoder = new TextDecoder("utf-8");
|
|
||||||
const reader = stream?.getReader();
|
|
||||||
let answer = "";
|
|
||||||
|
|
||||||
// Cache received response
|
|
||||||
const newResponse: RawMessage = {
|
|
||||||
conversationId: currentConvo?._id,
|
|
||||||
message: answer,
|
|
||||||
user: "assistant",
|
|
||||||
createdAt: new Date().toISOString(),
|
|
||||||
};
|
|
||||||
|
|
||||||
while (reader) {
|
|
||||||
const { done, value } = await reader.read();
|
|
||||||
if (done) {
|
|
||||||
console.log("SSE stream closed");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
const text = decoder.decode(value);
|
|
||||||
const lines = text.trim().split("\n");
|
|
||||||
for (const line of lines) {
|
|
||||||
if (line.startsWith("data: ") && !line.includes("data: [DONE]")) {
|
|
||||||
const data = JSON.parse(line.replace("data: ", ""));
|
|
||||||
answer += data.choices[0]?.delta?.content ?? "";
|
|
||||||
if (answer.startsWith("assistant: ")) {
|
|
||||||
answer = answer.replace("assistant: ", "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const updatedConvo: Conversation = {
|
|
||||||
...convo,
|
|
||||||
summary: answer.trim(),
|
|
||||||
};
|
|
||||||
|
|
||||||
console.debug(`Update convo: ${JSON.stringify(updatedConvo)}`);
|
|
||||||
await executeSerial(DataService.UpdateConversation, updatedConvo);
|
|
||||||
updateConversation(updatedConvo);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { NewMessageResponse } from "@janhq/plugin-core";
|
||||||
export enum MessageType {
|
export enum MessageType {
|
||||||
Text = "Text",
|
Text = "Text",
|
||||||
Image = "Image",
|
Image = "Image",
|
||||||
@ -33,12 +34,13 @@ export interface RawMessage {
|
|||||||
_id?: string;
|
_id?: string;
|
||||||
conversationId?: string;
|
conversationId?: string;
|
||||||
user?: string;
|
user?: string;
|
||||||
|
avatar?: string;
|
||||||
message?: string;
|
message?: string;
|
||||||
createdAt?: string;
|
createdAt?: string;
|
||||||
updatedAt?: string;
|
updatedAt?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const toChatMessage = (m: RawMessage): ChatMessage => {
|
export const toChatMessage = (m: RawMessage | NewMessageResponse): ChatMessage => {
|
||||||
const createdAt = new Date(m.createdAt ?? "").getTime();
|
const createdAt = new Date(m.createdAt ?? "").getTime();
|
||||||
const imageUrls: string[] = [];
|
const imageUrls: string[] = [];
|
||||||
const imageUrl = undefined;
|
const imageUrl = undefined;
|
||||||
@ -47,8 +49,7 @@ export const toChatMessage = (m: RawMessage): ChatMessage => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const messageType = MessageType.Text;
|
const messageType = MessageType.Text;
|
||||||
const messageSenderType =
|
const messageSenderType = m.user === "user" ? MessageSenderType.User : MessageSenderType.Ai;
|
||||||
m.user === "user" ? MessageSenderType.User : MessageSenderType.Ai;
|
|
||||||
|
|
||||||
const content = m.message ?? "";
|
const content = m.message ?? "";
|
||||||
|
|
||||||
@ -58,9 +59,8 @@ export const toChatMessage = (m: RawMessage): ChatMessage => {
|
|||||||
messageType: messageType,
|
messageType: messageType,
|
||||||
messageSenderType: messageSenderType,
|
messageSenderType: messageSenderType,
|
||||||
senderUid: m.user?.toString() || "0",
|
senderUid: m.user?.toString() || "0",
|
||||||
senderName: m.user === "user" ? "You" : "Assistant",
|
senderName: m.user === "user" ? "You" : m.user && m.user !== "ai" && m.user !== "assistant" ? m.user : "Assistant",
|
||||||
senderAvatarUrl:
|
senderAvatarUrl: m.avatar ? m.avatar : m.user === "user" ? "icons/avatar.svg" : "icons/app_icon.svg",
|
||||||
m.user === "user" ? "icons/avatar.svg" : "icons/app_icon.svg",
|
|
||||||
text: content,
|
text: content,
|
||||||
imageUrls: imageUrls,
|
imageUrls: imageUrls,
|
||||||
createdAt: createdAt,
|
createdAt: createdAt,
|
||||||
|
|||||||
@ -1,8 +1,21 @@
|
|||||||
import { store } from "./storeService";
|
import { store } from "./storeService";
|
||||||
|
import { EventEmitter } from "./eventsService";
|
||||||
|
|
||||||
export const setupCoreServices = () => {
|
export const setupCoreServices = () => {
|
||||||
|
if (typeof window === "undefined") {
|
||||||
|
console.log("undefine", window);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
console.log("Setting up core services");
|
||||||
|
}
|
||||||
if (!window.corePlugin) {
|
if (!window.corePlugin) {
|
||||||
window.corePlugin = {
|
window.corePlugin = {
|
||||||
store,
|
store,
|
||||||
|
events: new EventEmitter(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (!window.coreAPI) {
|
||||||
|
// fallback electron API
|
||||||
|
window.coreAPI = window.electronAPI;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
40
web/app/_services/eventsService.ts
Normal file
40
web/app/_services/eventsService.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
export class EventEmitter {
|
||||||
|
private handlers: Map<string, Function[]>;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.handlers = new Map<string, Function[]>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public on(eventName: string, handler: Function): void {
|
||||||
|
if (!this.handlers.has(eventName)) {
|
||||||
|
this.handlers.set(eventName, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.handlers.get(eventName)?.push(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public off(eventName: string, handler: Function): void {
|
||||||
|
if (!this.handlers.has(eventName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlers = this.handlers.get(eventName);
|
||||||
|
const index = handlers?.indexOf(handler);
|
||||||
|
|
||||||
|
if (index !== undefined && index !== -1) {
|
||||||
|
handlers?.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public emit(eventName: string, args: any): void {
|
||||||
|
if (!this.handlers.has(eventName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlers = this.handlers.get(eventName);
|
||||||
|
|
||||||
|
handlers?.forEach((handler) => {
|
||||||
|
handler(args);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
111
web/app/page.tsx
111
web/app/page.tsx
@ -1,76 +1,81 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
import { PluginService } from "@janhq/plugin-core";
|
||||||
import { ThemeWrapper } from "./_helpers/ThemeWrapper";
|
import { ThemeWrapper } from "./_helpers/ThemeWrapper";
|
||||||
import JotaiWrapper from "./_helpers/JotaiWrapper";
|
import JotaiWrapper from "./_helpers/JotaiWrapper";
|
||||||
import { ModalWrapper } from "./_helpers/ModalWrapper";
|
import { ModalWrapper } from "./_helpers/ModalWrapper";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import {
|
import { setup, plugins, activationPoints, extensionPoints } from "../../electron/core/plugin-manager/execution/index";
|
||||||
setup,
|
import { isCorePluginInstalled, setupBasePlugins } from "./_services/pluginService";
|
||||||
plugins,
|
|
||||||
activationPoints,
|
|
||||||
} from "../../electron/core/plugin-manager/execution/index";
|
|
||||||
import {
|
|
||||||
isCorePluginInstalled,
|
|
||||||
setupBasePlugins,
|
|
||||||
} from "./_services/pluginService";
|
|
||||||
import EventListenerWrapper from "./_helpers/EventListenerWrapper";
|
import EventListenerWrapper from "./_helpers/EventListenerWrapper";
|
||||||
import { setupCoreServices } from "./_services/coreService";
|
import { setupCoreServices } from "./_services/coreService";
|
||||||
import MainContainer from "./_components/MainContainer";
|
import MainContainer from "./_components/MainContainer";
|
||||||
|
import { executeSerial } from "../../electron/core/plugin-manager/execution/extension-manager";
|
||||||
|
|
||||||
const Page: React.FC = () => {
|
const Page: React.FC = () => {
|
||||||
|
const [setupCore, setSetupCore] = useState(false);
|
||||||
const [activated, setActivated] = useState(false);
|
const [activated, setActivated] = useState(false);
|
||||||
|
|
||||||
|
async function setupPE() {
|
||||||
|
// Enable activation point management
|
||||||
|
setup({
|
||||||
|
importer: (plugin: string) =>
|
||||||
|
import(/* webpackIgnore: true */ plugin).catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Register all active plugins with their activation points
|
||||||
|
await plugins.registerActive();
|
||||||
|
setTimeout(async () => {
|
||||||
|
// Trigger activation points
|
||||||
|
await activationPoints.trigger("init");
|
||||||
|
if (!isCorePluginInstalled()) {
|
||||||
|
setupBasePlugins();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (extensionPoints.get(PluginService.OnStart)) {
|
||||||
|
await executeSerial(PluginService.OnStart);
|
||||||
|
}
|
||||||
|
setActivated(true);
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
|
||||||
// Services Setup
|
// Services Setup
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Setup Core Service
|
|
||||||
setupCoreServices();
|
setupCoreServices();
|
||||||
|
setSetupCore(true);
|
||||||
async function setupPE() {
|
|
||||||
// Enable activation point management
|
|
||||||
setup({
|
|
||||||
importer: (plugin: string) =>
|
|
||||||
import(/* webpackIgnore: true */ plugin).catch((err) => {
|
|
||||||
console.log(err);
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
// Register all active plugins with their activation points
|
|
||||||
await plugins.registerActive();
|
|
||||||
setTimeout(async () => {
|
|
||||||
// Trigger activation points
|
|
||||||
await activationPoints.trigger("init");
|
|
||||||
if (!isCorePluginInstalled()) {
|
|
||||||
setupBasePlugins();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setActivated(true);
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
// Electron
|
|
||||||
if (window && window.electronAPI) {
|
|
||||||
setupPE();
|
|
||||||
} else {
|
|
||||||
// Host
|
|
||||||
setActivated(true);
|
|
||||||
}
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (setupCore) {
|
||||||
|
// Electron
|
||||||
|
if (window && window.electronAPI) {
|
||||||
|
setupPE();
|
||||||
|
} else {
|
||||||
|
// Host
|
||||||
|
setActivated(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [setupCore]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<JotaiWrapper>
|
<JotaiWrapper>
|
||||||
<EventListenerWrapper>
|
{setupCore && (
|
||||||
<ThemeWrapper>
|
<EventListenerWrapper>
|
||||||
<ModalWrapper>
|
<ThemeWrapper>
|
||||||
{activated ? (
|
<ModalWrapper>
|
||||||
<MainContainer />
|
{activated ? (
|
||||||
) : (
|
<MainContainer />
|
||||||
<div className="bg-white w-screen h-screen items-center justify-center flex">
|
) : (
|
||||||
<Image width={50} height={50} src="icons/app_icon.svg" alt="" />
|
<div className="bg-white w-screen h-screen items-center justify-center flex">
|
||||||
</div>
|
<Image width={50} height={50} src="icons/app_icon.svg" alt="" />
|
||||||
)}
|
</div>
|
||||||
</ModalWrapper>
|
)}
|
||||||
</ThemeWrapper>
|
</ModalWrapper>
|
||||||
</EventListenerWrapper>
|
</ThemeWrapper>
|
||||||
|
</EventListenerWrapper>
|
||||||
|
)}
|
||||||
</JotaiWrapper>
|
</JotaiWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@headlessui/react": "^1.7.15",
|
"@headlessui/react": "^1.7.15",
|
||||||
"@heroicons/react": "^2.0.18",
|
"@heroicons/react": "^2.0.18",
|
||||||
"@janhq/plugin-core": "file:../plugin-core",
|
"@janhq/plugin-core": "^0.1.8",
|
||||||
"@tailwindcss/typography": "^0.5.9",
|
"@tailwindcss/typography": "^0.5.9",
|
||||||
"@types/react": "18.2.15",
|
"@types/react": "18.2.15",
|
||||||
"@types/react-dom": "18.2.7",
|
"@types/react-dom": "18.2.7",
|
||||||
|
|||||||
1
web/types/index.d.ts
vendored
1
web/types/index.d.ts
vendored
@ -4,5 +4,6 @@ declare global {
|
|||||||
interface Window {
|
interface Window {
|
||||||
electronAPI?: any | undefined;
|
electronAPI?: any | undefined;
|
||||||
corePlugin?: any | undefined;
|
corePlugin?: any | undefined;
|
||||||
|
coreAPI?: any | undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user