Merge branch 'devhub' of https://github.com/janhq/jan into devhub

This commit is contained in:
0xSage 2023-10-27 10:59:48 +07:00
commit 68f25da15b
7 changed files with 280 additions and 4 deletions

View File

@ -4,9 +4,18 @@ title: Anatomy of an app
--- ---
## Jan Architecture ## Jan Architecture
### High level architecture
![High level architecture](img/architecture-0.drawio.png)
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
![Overall architecture](img/architecture-1.drawio.png) At Jan, we strongly believe in `portable AI` that is created once and run anywhere.
### Low level architecture
![Low level architecture](img/architecture-1.drawio.png)
- Jan platform includes the following components: - Jan platform includes the following components:
- Processes: - Processes:

View File

@ -3,4 +3,110 @@ sidebar_position: 1
title: Build an app 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
![Manual installation](img/build-app-1.png)
- `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`

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

View File

@ -1,3 +1,3 @@
--- ---
title: Installing Jan on Linux title: Installing Jan on Mac
--- ---

View File

@ -1,3 +1,3 @@
--- ---
title: Installing Jan on Linux title: Installing Jan on Windows
--- ---

View 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.