Merge branch 'devhub' of https://github.com/janhq/jan into devhub
This commit is contained in:
commit
68f25da15b
@ -4,9 +4,18 @@ title: Anatomy of an app
|
||||
---
|
||||
|
||||
## Jan Architecture
|
||||
### High level architecture
|
||||

|
||||
Jan mission is to power the next gen App with the limitless extensibility by providing BUILDER:
|
||||
- Unified API/ Helpers so that they only need to care about what matters
|
||||
- Wide range of Optimized and State of the art models that can help your App with Thinking/ Hearing/ Seeing capabilities. This is powered by our [Nitro](https://github.com/janhq/nitro)
|
||||
- Strong support for App marketplace and Model market place that streamline value from end customers to builders at all layers
|
||||
- The most important: The user of Jan can use the Apps via UI and API for integration
|
||||
|
||||

|
||||
At Jan, we strongly believe in `portable AI` that is created once and run anywhere.
|
||||
|
||||
### Low level architecture
|
||||

|
||||
- Jan platform includes the following components:
|
||||
|
||||
- Processes:
|
||||
|
||||
@ -3,4 +3,110 @@ sidebar_position: 1
|
||||
title: Build an app
|
||||
---
|
||||
|
||||
TODO: quickstart tutorial
|
||||
# Build and publish an app
|
||||
Apps let you extend Obsidian with your own features to create a custom note-taking experience.
|
||||
In this tutorial, you'll compile a sample plugin from source code and load it into Obsidian.
|
||||
|
||||
## What you'll learn
|
||||
After you've completed this tutorial, you'll be able to:
|
||||
- Configure an environment for developing Jan apps.
|
||||
- Compile a app from source code.
|
||||
- Reload a app after making changes to it.
|
||||
|
||||
## Prerequisites
|
||||
To complete this tutorial, you'll need:
|
||||
- [Git](https://git-scm.com/) installed on your local machine.
|
||||
- A local development environment for [Node.js](https://node.js.org/en/about/).
|
||||
- A code editor, such as [Visual Studio Code](https://code.visualstudio.com/).
|
||||
|
||||
## Before you start
|
||||
When developing apps, one mistake can lead to unintended changes to your app. Please backup the data.
|
||||
|
||||
## Development
|
||||
### Step 1: Download the sample plugin
|
||||
- Go to [Jan sample app](https://github.com/janhq/jan-sample-app)
|
||||
- Select `Use this template button` at the top of the repository
|
||||
- Select `Create a new repository`
|
||||
- Select an owner and name for your new repository
|
||||
- Click `Create repository`
|
||||
- Clone your new repository
|
||||
- Start developing locally
|
||||
|
||||
### Step 2: Initial Setup
|
||||
|
||||
After you've cloned the repository to your local machine or codespace, you'll need to perform some initial setup steps before you can develop your plugin.
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
> You'll need to have a reasonably modern version of
|
||||
> [Node.js](https://nodejs.org) handy. If you are using a version manager like
|
||||
> [`nodenv`](https://github.com/nodenv/nodenv) or
|
||||
> [`nvm`](https://github.com/nvm-sh/nvm), you can run `nodenv install` in the
|
||||
> root of your repository to install the version specified in
|
||||
> [`package.json`](./package.json). Otherwise, 20.x or later should work!
|
||||
|
||||
1. :hammer_and_wrench: Install the dependencies
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
1. :building_construction: Package the TypeScript for distribution
|
||||
|
||||
```bash
|
||||
npm run bundle
|
||||
```
|
||||
|
||||
1. :white_check_mark: Check your artifact
|
||||
|
||||
There will be a tgz file in your plugin directory now
|
||||
|
||||
### Step 3: Update the Plugin Metadata
|
||||
|
||||
The [`package.json`](package.json) file defines metadata about your plugin, such as
|
||||
plugin name, main entry, description and version.
|
||||
|
||||
When you copy this repository, update `package.json` with the name, description for your plugin.
|
||||
|
||||
### Step 4: Update the Plugin Code
|
||||
|
||||
The [`src/`](./src/) directory is the heart of your plugin! This contains the
|
||||
source code that will be run when your plugin extension functions are invoked. You can replace the
|
||||
contents of this directory with your own code.
|
||||
|
||||
There are a few things to keep in mind when writing your plugin code:
|
||||
|
||||
- Most Jan Plugin Extension functions are processed asynchronously.
|
||||
In `index.ts`, you will see that the extension function will return a `Promise<any>`.
|
||||
|
||||
```typescript
|
||||
import { core } from "@janhq/core";
|
||||
|
||||
function onStart(): Promise<any> {
|
||||
return core.invokePluginFunc(MODULE_PATH, "run", 0);
|
||||
}
|
||||
```
|
||||
|
||||
For more information about the Jan Plugin Core module, see the
|
||||
[documentation](https://github.com/janhq/jan/blob/main/core/README.md).
|
||||
|
||||
So, what are you waiting for? Go ahead and start customizing your plugin!
|
||||
|
||||
## App installation
|
||||

|
||||
- `Select` the built `*.tar.gz` file
|
||||
- The App will reload after new app get installed
|
||||
|
||||
## App uninstallation
|
||||
To be updated
|
||||
|
||||
## App update
|
||||
To be updated
|
||||
|
||||
## App publish
|
||||
After you have completed with local app development and want to publish to `Jan marketplace` for other to reuse, please follow the following steps
|
||||
- Update your local `package.json` and configure `npm login` correctly
|
||||
- Run `npm publish` and set to public NPM package (so that other can install) - Please refer to our example [NPM retrieval plugin](https://www.npmjs.com/package/retrieval-plugin)
|
||||
- Go to `Jan plugin catalog`(https://github.com/janhq/plugin-catalog) and create a `Pull request` for new `App artifact` (which is a renamed version of your App `package.json`) - Please refer to example [retrieval-plugin](https://github.com/janhq/plugin-catalog/blob/main/retrieval-plugin.json)
|
||||
- We at Jan will be responsible to review and merge to `main`
|
||||
- Once your new app is on `main`, you and other Jan users can find it in `Jan marketplace`
|
||||
BIN
docs/docs/getting-started/img/architecture-0.drawio.png
Normal file
BIN
docs/docs/getting-started/img/architecture-0.drawio.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 47 KiB |
BIN
docs/docs/getting-started/img/build-app-1.png
Normal file
BIN
docs/docs/getting-started/img/build-app-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 232 KiB |
@ -1,3 +1,3 @@
|
||||
---
|
||||
title: Installing Jan on Linux
|
||||
title: Installing Jan on Mac
|
||||
---
|
||||
@ -1,3 +1,3 @@
|
||||
---
|
||||
title: Installing Jan on Linux
|
||||
title: Installing Jan on Windows
|
||||
---
|
||||
161
docs/docs/reference/data_plugin.md
Normal file
161
docs/docs/reference/data_plugin.md
Normal file
@ -0,0 +1,161 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
title: "data plugin"
|
||||
---
|
||||
|
||||
## Data Plugin
|
||||
|
||||
> This module provides functions for interacting with data storage using ([PouchDB](https://github.com/pouchdb/pouchdb)) as the underlying database.
|
||||
|
||||
## Usage
|
||||
|
||||
### Create a collection
|
||||
In this example, we will create a collection named `my-collection` without schema. The database will be located as at: `AppData + /dabatases/my-collection`. AppData will depends on your OS where you install Jan app:
|
||||
AppData Per-user application data directory, which by default points to:
|
||||
* %APPDATA% on Windows
|
||||
* $XDG_CONFIG_HOME or ~/.config on Linux
|
||||
* ~/Library/Application Support on macOS
|
||||
|
||||
For example, the database location in macOS would be `/Users/$(whoami)/Library/Application\ Support/jan/databases/my-collection`
|
||||
```js
|
||||
const store = require("@janhq/core");
|
||||
store.createCollection({ name: "my-collection", schema: {} });
|
||||
```
|
||||
### Delete a collection
|
||||
Delete `my-collection` database.
|
||||
```js
|
||||
const store = require("@janhq/core");
|
||||
store.deleteCollection({"my-collection"});
|
||||
```
|
||||
### Create a document
|
||||
In this example, we'll create a document in `my-collection` database. The document comprises 3 field : `_id: string` , `name: string`, `age: number`. The `insertOne` function will return inserted id.
|
||||
```js
|
||||
const store = require("@janhq/core");
|
||||
const id = await store.insertOne("my-collection", {_id: "1", name: "Jan", age: 1});
|
||||
// id = 1
|
||||
```
|
||||
|
||||
### Find one document
|
||||
In the previous step, we just created a document with `_id:"1"`. Let's try how to find it.
|
||||
```js
|
||||
const store = require("@janhq/core");
|
||||
const doc = await store.findOne("my-collection","1");
|
||||
// {name: 'Jan', age: 1, _id: '1'}
|
||||
```
|
||||
|
||||
### Find many documents and sort the result
|
||||
In this example, we will find all the documents that have `age >= 1` with `$gte` operator and sort the result by name in descending order.
|
||||
```js
|
||||
const store = require("@janhq/core");
|
||||
const id1 = await store.insertOne("my-collection", {_id: "1", name: "Jan", age: 1});
|
||||
const id2 = await store.insertOne("my-collection", {_id: "2", name: "James", age: 1});
|
||||
const id3 = await store.insertOne("my-collection", {_id: "3", name: "Jack", age: 2});
|
||||
const docs = await store.findMany("my-collection", {age: { $gte: 1 }}, [{ name : "desc"}]);
|
||||
// [{"name":"Jan","age":1,"_id":"1",},
|
||||
// {"name":"James","age":1,"_id":"2"},
|
||||
// {"name":"Jack","age":2,"_id":"3"}]
|
||||
```
|
||||
For more operators, please follow:
|
||||
* $lt Match fields “less than” this one.
|
||||
* $gt Match fields “greater than” this one.
|
||||
* $lte Match fields “less than or equal to” this one.
|
||||
* $gte Match fields “greater than or equal to” this one.
|
||||
* $eq Match fields equal to this one.
|
||||
* $ne Match fields not equal to this one.
|
||||
* $exists True if the field should exist, false otherwise.
|
||||
* $type One of: “null”, “boolean”, “number”, “string”, “array”, or “object”.
|
||||
* $in The document field must exist in the list provided.
|
||||
* $and Matches if all the selectors in the array match.
|
||||
* $nin The document field must not exist in the list provided.
|
||||
* $all Matches an array value if it contains all the elements of the argument array.
|
||||
* $size Special condition to match the length of an array field in a document.
|
||||
* $or Matches if any of the selectors in the array match. All selectors must use the same index.
|
||||
* $nor Matches if none of the selectors in the array match.
|
||||
* $not Matches if the given selector does not match.
|
||||
* $mod Matches documents where (field % Divisor == Remainder) is true, and only when the document field is an integer.
|
||||
* $regex A regular expression pattern to match against the document field.
|
||||
* $elemMatch Matches all documents that contain an array field with at least one element that matches all the specified query criteria.
|
||||
|
||||
### Update a document
|
||||
In this example, we will change the age from `1 to 5` in the document that has the id of `"1"`
|
||||
```js
|
||||
const store = require("@janhq/core");
|
||||
const id = await store.insertOne("my-collection", {_id: "1", name: "Jan", age: 1});
|
||||
await store.updateOne("my-collection", "1", {name: "Jan", age: 5});
|
||||
```
|
||||
|
||||
### Update many documents
|
||||
In this example, we will update the age to `10` in the documents that have `age >= 1`
|
||||
```js
|
||||
const store = require("@janhq/core");
|
||||
const id1 = await store.insertOne("my-collection", {_id: "1", name: "Jan", age: 1});
|
||||
const id2 = await store.insertOne("my-collection", {_id: "2", name: "James", age: 1});
|
||||
const id3 = await store.insertOne("my-collection", {_id: "3", name: "Jack", age: 2});
|
||||
const docs = await store.updateMany("my-collection", {age:10}, {age: { $gte : 1 }});
|
||||
// [{"name":"Jan","age":10,"_id":"1",},
|
||||
// {"name":"James","age":10,"_id":"2"},
|
||||
// {"name":"Jack","age":10,"_id":"3"}]
|
||||
```
|
||||
For more operators, please follow:
|
||||
* $lt Match fields “less than” this one.
|
||||
* $gt Match fields “greater than” this one.
|
||||
* $lte Match fields “less than or equal to” this one.
|
||||
* $gte Match fields “greater than or equal to” this one.
|
||||
* $eq Match fields equal to this one.
|
||||
* $ne Match fields not equal to this one.
|
||||
* $exists True if the field should exist, false otherwise.
|
||||
* $type One of: “null”, “boolean”, “number”, “string”, “array”, or “object”.
|
||||
* $in The document field must exist in the list provided.
|
||||
* $and Matches if all the selectors in the array match.
|
||||
* $nin The document field must not exist in the list provided.
|
||||
* $all Matches an array value if it contains all the elements of the argument array.
|
||||
* $size Special condition to match the length of an array field in a document.
|
||||
* $or Matches if any of the selectors in the array match. All selectors must use the same index.
|
||||
* $nor Matches if none of the selectors in the array match.
|
||||
* $not Matches if the given selector does not match.
|
||||
* $mod Matches documents where (field % Divisor == Remainder) is true, and only when the document field is an integer.
|
||||
* $regex A regular expression pattern to match against the document field.
|
||||
* $elemMatch Matches all documents that contain an array field with at least one element that matches all the specified query criteria.
|
||||
|
||||
### Delete a document
|
||||
Delete the document which has id of `"1"`
|
||||
```js
|
||||
const store = require("@janhq/core");
|
||||
const id1 = await store.insertOne("my-collection", {_id: "1", name: "Jan", age: 1});
|
||||
const doc = await store.deleteOne("my-collection","1");
|
||||
```
|
||||
### Delete many documents
|
||||
In this exmaple, we will delete documents that have `age < 2`
|
||||
```js
|
||||
const store = require("@janhq/core");
|
||||
const id1 = await store.insertOne("my-collection", {_id: "1", name: "Jan", age: 1});
|
||||
const id2 = await store.insertOne("my-collection", {_id: "2", name: "James", age: 1});
|
||||
const id3 = await store.insertOne("my-collection", {_id: "3", name: "Jack", age: 2});
|
||||
const docs = await store.deleteMany("my-collection", {age: {$lt : 2}});
|
||||
```
|
||||
For more operators, please follow:
|
||||
* $lt Match fields “less than” this one.
|
||||
* $gt Match fields “greater than” this one.
|
||||
* $lte Match fields “less than or equal to” this one.
|
||||
* $gte Match fields “greater than or equal to” this one.
|
||||
* $eq Match fields equal to this one.
|
||||
* $ne Match fields not equal to this one.
|
||||
* $exists True if the field should exist, false otherwise.
|
||||
* $type One of: “null”, “boolean”, “number”, “string”, “array”, or “object”.
|
||||
* $in The document field must exist in the list provided.
|
||||
* $and Matches if all the selectors in the array match.
|
||||
* $nin The document field must not exist in the list provided.
|
||||
* $all Matches an array value if it contains all the elements of the argument array.
|
||||
* $size Special condition to match the length of an array field in a document.
|
||||
* $or Matches if any of the selectors in the array match. All selectors must use the same index.
|
||||
* $nor Matches if none of the selectors in the array match.
|
||||
* $not Matches if the given selector does not match.
|
||||
* $mod Matches documents where (field % Divisor == Remainder) is true, and only when the document field is an integer.
|
||||
* $regex A regular expression pattern to match against the document field.
|
||||
* $elemMatch Matches all documents that contain an array field with at least one element that matches all the specified query criteria.
|
||||
|
||||
## How to contribute
|
||||
1. Go to [Jan](https://github.com/janhq/jan)
|
||||
2. Create an Issue for plugins
|
||||
3. Create a PR to `main` branch
|
||||
4. Once it's merged, the new model will be on Jan plugin to use.
|
||||
Loading…
x
Reference in New Issue
Block a user