This is a DEMO! Click here to access the full version.

Documentation

The JinkoNo Platform works similar to an Operating System, so many of the concepts presented in this documentation will almost always refer to ideas from OS, so for a better understanding keep this in mind.

Contents

  1. Notes
    1. Key restrictions
    2. Markdown
  2. Tagging
    1. Special tags
  3. Scripting
    1. API reference
      1. Libraries
      2. Typed tag object
      3. Functions
      4. Components
      5. Objects
  4. Commands
  5. Hotkeys
  6. Best practices
  7. Extension

Notes

They work similary to a file in an OS, it can be pure data or it can become a process depending on the situation. The big difference from files is that notes can have arbitrary tags attached to it.

A note is composed by:

  • Key is used to identify/index/reference a note in the system, they are divided by / where each previously part could be considered to be directories per say. Although is not enforced we always recommend to end the key with an appropriate format, like .json .md .jpg .js.
  • Tags are metadata attached to a particular note that should be used to describe a particular aspect of the note content. Be aware that there is a limit of 2 KB after encryption for all note tags. We'll focus more about it in this section
  • Content is the actual data stored in the note, it can be either text or midia. The size of the content has a limit of 5 MB.

Important: if you want to display a midia note inside a text note you will need to prefix it with vault: followed by the key, e.g. ![This is me](vault:me.jpg).

Key restrictions

There are a few restrictions for keys that you need to be aware, they are:

  • Valid characters are: [0-9] [a-z] [A-Z] / _ - ' .
  • Cannot start with . or/
  • There is a size limit of 256 characters

There are also special key patterns that defines an exceptional note purpose, they are:

  • hotkeys.json: for custom hotkeys configuration. See more in this section.
  • extension/scrapers.json: for browser extension scraper definition, see more here.
  • script/*.js: for notes that behave as scripts, see more here.

Markdown

We support Github Flavored Markdown and a few addicional components, for easier use we have a few alias:

  • You can type |3x2|<space> to create a table with 3 lines and 2 rows.
  • You can type $$<space> to create a math block.
  • You can type ```mermaid to add diagrams.

Tips: use <mod>+<enter> to exit blocks such as code block.

Tagging

Tags are used to attach metadata directly to the note itself, this integrates nicely into the rest of the system through commands.

A tag is composed by a list of nodes that are separated by a <space /> key. We strongly recommend using PascalCase for each tag node.

Personality Enthusiastic +++

This tag could be attached to a note describing a person that is very(+++) enthusiastic.

There are special typed tags that are capable of storing specific information within the following categories:

  • Reference: use this to create a reference to another note or execute a script. If the note referenced is a script, when clicked it will execute the script with args.openedBy as the note key. Tip: use keywords to define the relationship type, e.g. Used $REF(#toy_id) When $REF(#game_id).

    When referencing a script and you click in the tag it will execute the script instead of open it.

  • Link: used to link to an external site, e.g. Source $URL(wikipedia).
  • Map: integration with Google Maps Embed API, e.g. Address $MAP(place/Tokyo).
  • Date: define a particular date, e.g. Birthday $DATE(01/01/1990).
  • Time: define a time of the day, e.g. Lunch $TIME(12:00PM).
  • Datetime: define a particular point in time, e.g. Singularity $DATETIME(21/12/33).
  • Duration: define a time interval, e.g. 100mRun $DURATION(11532ms).

Special tags

Special tags have a particular behavior attached to it. They always start with ! character. Currently we have the following special tags:

  • !Opened

    { type: ref, key: script/something.js }

    When opening a note with this tag it will automatically execute the script referenced. The reference must be to a script note.

Scripting

A script is a piece of code that produce a particular behavior that is beneficial to the understanding/processing of notes. This gives much more power/flexibility then any arbitrary functionality that we could hard code into the system.

We use JavaScript as the core system language, and a few libraries are inserted by default, they are Preact and D3.

API reference

You can access the arguments that are passed via commands through the args object.

Default arguments

  • args.env: it can be either dev when running from manually saving the note or prod when running from a command.
  • args.openedBy: if the script was opened by a Script Tag then this variable will store the note key that opened it.
  • args.carry: carries the returned value of the last command script that was pipe into it. Consider that script_a.js always return the valie 5, then the command >> script_a.js >> script_b.js will make script_b.js have args.carry === 5.

Libraries

  • React: is a JavaScript library for creating user interfaces.
  • d3: is a JavaScript library for visualizing data using web standards.
  • OpenAI: provides convenient access to the OpenAI REST API from TypeScript or JavaScript.
  • z: schema validation with static type inference.
  • create: a zustand store with Immer middleware.

Typed tag object

A common tag will have a simple string type. But for typed tags it will have one of these schemes:

  • Reference: { type: "ref", key: string }
  • Link: { type: "link", url: string }
  • Map: { type: "date", params: { mapmode: GMMode } & GMParams<mode> }

    field GMMode is one of these values and GMParams<mode> is the corresponding parameters for the mode defined by mapmode.

  • Date: { type: "date", date: number }

    field date is in milliseconds

  • Time: { type: "time", time: number }

    field time is in milliseconds

  • Datetime: { type: "datetime", datetime: number }

    field datetime is in milliseconds

  • Duration: { type: "duration", duration: number }

    field duration is in milliseconds

There are a few build-in functions and components that facilitate the scripts implementation, there are:

Functions

render(tabName: string, component: JSX.Element) => void

Render the component in the tab identified by tabName.

Parameters

  • tabName: defines the tab name where the component will be renderer, if there already is a tab with this name the it will replace it.
  • component: define what it will be renderer under the tab specified.
list(path: string) => Promise<Array<Item | Path>>

List all the notes keys or partial valid paths for a given path.

Parameters

  • path: defines the tab name where the component will be renderer, if there already is a tab with this name the it will replace it.

Returns

  • Item
    • type: "item": used to identify if the array element is of type Item.
    • key: string: the note key value.
    • lastModified: Date: the last time the note was modified.
  • Path
    • type: "path": used to identify if the array element is of type Path.
    • path: string: the partial path under the given path.
retrieve(keys: Array<string>) => Promise<Array<Note | null>>

Retrieves the notes indexed by the given keys in the order it was given. The typed tags are automatically decoded to the appropriate object format.

Parameters

  • keys: an array of the note keys in the desired order that you want to retrieve.

Returns

  • Note | null if unable to find the note indexed by the corresponding key it will be null instead.
    • key: string: the note key value.
    • tags: Array<Array<Tag>>: first array is each tag, the second is each tag node. Important: don't use <space> in a tag node string.
    • lastModified: Date: the last time the note was modified.
    • content: string: the note content.
upsert(note: UpsertNote) => Promise<void>

Create or update note if it already exists. Important: typed tags should be sent as the correct object! Make sure you're following the appropriate scheme for the typed tag that you want.

Parameters

  • note: the note that will be upserted.
    • key: string: the note key value.
    • tags: Array<Array<Tag>>: first array is each tag, the second is each tag node. Important: don't use <space> in a tag node string.
    • content: string: the note content.
loadStyle(path?: string) => Promise<void>

Will load a stylesheet into the DOM.

Parameters

  • path: the style note path. If not path is provided it will fallback to the default value of asset/style.css.
error(error: Error) => void

Will display an error in the DOM.

Parameters

  • error: the error to display.

Objects

schema

Used to validate multiple important types.

Properties

  • tag: ZodTypeFor<TypedTagNode>: a ZodType used to validate typed tag's nodes.
  • key: (v: string) => boolean: check if a key value is valid.

Components

<MapView width height config style? />

Render a Google Map iframe component with a given configuration.

  • width: number: the width of the map component
  • height: number: the height of the map component
  • config: { mapmode: GMMode } & GMParams<mode>: the google maps configuration, it will be the mapTag.params value.
  • style: string: html inline style of the iframe component.
<Markdown children />

Render the children string as a Markdown component.

  • children: string: the content of the Markdown.

Commands

Commands are inputs given to the terminal in the bottom besides the gear icon. They are useful for piping/processing scripts.

  • new note|midia [key] create a new note or upload a midia with the given key.
  • delete [key] deletes the note with the given key.
  • edit [key] opens the editor for the note with the given key.
  • |>, >> used to execute an script pipeline.
    • |> it break the previous pipe, if any, and don't carry nothing to the following script.
    • >> it passes the return value from the previous script to args.carry variable.
    To pass arguments to a particular script use this pattern --[key] value. For example:
    • >> script.js --num 123 --str Hi there man --obj {a:1,b:"hi"} You can access this values using the args object, which in this case would be {num: "123", str: "Hi there man", obj: '{a:1,b:"hi"}'}
    If the script is running from a save action in the editor it will have args.env == "dev", otherwise it will be args.env == "prod".
  • command [command] fill the command input with the [command] value. This is useful to make a custom auto complete functionality.
  • press back|forward|collapse press a button programmatically.
  • layout [editor_grow] [sandbox_grow] change the layout for large viewports, e.g. layout 2 1 will make the editor have 66.6% width and sandbox have 33.3% of the available width.

You can use @this as an alias to the opened note key. So if you want to delete the note that is opened you can just use the command delete @this instead of writing the note key.

Hotkeys

You can set hotkeys to execute a command. Just edit the hotkeys.json file following the Array<{ hotkey: string; command: string }> schemes. Use the + sign to make it multiple, like ctrl+a or space+b.

Hover over buttons to see if there is a hotkey associated with it.

Important: For every hotkey it is always automatically added the super key, which alt. So if you use hotkey: "a" you will need to press alt+a to execute the command.

Important: If you're focusing in the Sandbox area the hotkeys won't work. This gives the possibility for you to implement you're own hotkeys under that context.

Best practices

We recommend creating very small notes and use tags to highlight important information of the note content that can be computed programmatically by script notes. Also you can use them to give aditional visualization capabilities of the content with script tags.

For example, instead of creating a Map of Content note, you can add a tag MoC Science to the relevant notes. And then with a script note visualize it based on that particular tag.

Extension

We have a browser extension that gives you access to automatically write notes from any content that you consume in the web. This can make the experience of writing notes much more seamless and standardized.

The extension uses scrapers defined by you. To write the scrapers that the extension will be using edit the note under the key extension/scrapers.json containing an array of ExtensionScraper i.e. Array<ExtensionScraper> where:

Loading...
☺ We are still in Beta version, much more to come ☺