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
- Notes
- Key restrictions
- Markdown
- Tagging
- Special tags
- Scripting
- API reference
- Libraries
- Typed tag object
- Functions
- Components
- Objects
- Commands
- Hotkeys
- Best practices
- 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
ormidia
. 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 eitherdev
when running from manually saving the note orprod
when running from a command.args.openedBy
: if the script was opened by aScript 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 thatscript_a.js
alwaysreturn
the valie 5, then the command>> script_a.js >> script_b.js
will makescript_b.js
haveargs.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 benull
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 ofasset/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>
: aZodType
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 componentheight: number
: the height of the map componentconfig: { mapmode: GMMode } & GMParams<mode>
: the google maps configuration, it will be themapTag.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 toargs.carry
variable.
--[key] value
. For example:>> script.js --num 123 --str Hi there man --obj {a:1,b:"hi"}
You can access this values using theargs
object, which in this case would be{num: "123", str: "Hi there man", obj: '{a:1,b:"hi"}'}
save
action in the editor it will haveargs.env == "dev"
, otherwise it will beargs.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 theeditor
have 66.6% width andsandbox
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: