diff --git a/docs/docs/getting-started/app-anatomy.md b/docs/docs/getting-started/app-anatomy.md index afcdea55c..0297d253a 100644 --- a/docs/docs/getting-started/app-anatomy.md +++ b/docs/docs/getting-started/app-anatomy.md @@ -4,9 +4,18 @@ title: Anatomy of an app --- ## 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: - Processes: diff --git a/docs/docs/getting-started/build-an-app.md b/docs/docs/getting-started/build-an-app.md index 6ede71756..343605011 100644 --- a/docs/docs/getting-started/build-an-app.md +++ b/docs/docs/getting-started/build-an-app.md @@ -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`. + + ```typescript + import { core } from "@janhq/core"; + + function onStart(): Promise { + 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` \ No newline at end of file diff --git a/docs/docs/getting-started/img/architecture-0.drawio.png b/docs/docs/getting-started/img/architecture-0.drawio.png new file mode 100644 index 000000000..55534a7e2 Binary files /dev/null and b/docs/docs/getting-started/img/architecture-0.drawio.png differ diff --git a/docs/docs/getting-started/img/build-app-1.png b/docs/docs/getting-started/img/build-app-1.png new file mode 100644 index 000000000..36538ce9c Binary files /dev/null and b/docs/docs/getting-started/img/build-app-1.png differ diff --git a/docs/docs/guides/mac.md b/docs/docs/guides/mac.md index a43b6eecb..315c3bf68 100644 --- a/docs/docs/guides/mac.md +++ b/docs/docs/guides/mac.md @@ -1,3 +1,3 @@ --- -title: Installing Jan on Linux +title: Installing Jan on Mac --- \ No newline at end of file diff --git a/docs/docs/guides/windows.md b/docs/docs/guides/windows.md index a43b6eecb..18c61a4fb 100644 --- a/docs/docs/guides/windows.md +++ b/docs/docs/guides/windows.md @@ -1,3 +1,3 @@ --- -title: Installing Jan on Linux +title: Installing Jan on Windows --- \ No newline at end of file diff --git a/docs/docs/reference/data_plugin.md b/docs/docs/reference/data_plugin.md new file mode 100644 index 000000000..bf8780734 --- /dev/null +++ b/docs/docs/reference/data_plugin.md @@ -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.