Skip to content

Commit

Permalink
Docs (#1)
Browse files Browse the repository at this point in the history
* +pages

* autotest+emedware

* integrations

* auto

* test timezone

* v4

* doc-ing

* prettier
  • Loading branch information
eddow authored Apr 30, 2024
1 parent cb0f1ea commit 13c43e4
Show file tree
Hide file tree
Showing 26 changed files with 1,247 additions and 123 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions

name: Node.js CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
build:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [18, 20, 21]

steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm install
- run: npm run build
- run: npm run test
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
node_modules
/dist
/.svelte-kit
/semantic
.env.*
!.env.example
.vercel
Expand All @@ -12,5 +11,6 @@ node_modules
/static/modules
/raw
/temp
/coverage
.vercel
.vscode/settings.json
10 changes: 7 additions & 3 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
node_modules
test
/node_modules
/test
/coverage
/docs
.*
*.config.js
*.config.json
*.config.json
.gitignore
/.svelte-kit
7 changes: 2 additions & 5 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/tsx",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"skipFiles": [
"<node_internals>/**",
"${workspaceFolder}/node_modules/**",
],
"skipFiles": ["<node_internals>/**", "${workspaceFolder}/node_modules/**"]
}
]
}
}
29 changes: 23 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
[![view on npm](https://badgen.net/npm/v/omni18n)](https://www.npmjs.org/package/omni18n)
[![npm module downloads](https://badgen.net/npm/dt/omni18n)](https://www.npmjs.org/package/omni18n)
[![Gihub repo dependents](https://badgen.net/github/dependents-repo/emedware/omni18n)](https://github.com/emedware/omni18n/network/dependents?dependent_type=REPOSITORY)
[![Gihub package dependents](https://badgen.net/github/dependents-pkg/emedware/omni18n)](https://github.com/emedware/omni18n/network/dependents?dependent_type=PACKAGE)
[![Node.js CI](https://github.com/emedware/omni18n/actions/workflows/node.js.yml/badge.svg)](https://github.com/emedware/omni18n/actions/workflows/node.js.yml)

<!-- [![Coverage Status](https://coveralls.io/repos/github/emedware/omni18n/badge.svg)](https://coveralls.io/github/emedware/omni18n) -->

# omni18n

Generic i18n library managing the fullstack interaction in a CI/CD pace. The fact the dictionaries are stored in a DB edited by the translators through a(/the same) web application - managing translation errors, missing keys, ...

It can even manage update of all (concerned) clients when a translation is modified

The main documentation on [GitHub pages](https://emedware.github.io/omni18n/) or in [the repository](./docs/README.md)

## General structure

The library is composed of a server part and a client part.
Expand Down Expand Up @@ -34,6 +44,8 @@ console.log(T('msg.hello'))

The full-stack case will insert the http protocol between `client` and `server`. The `condense` function takes few arguments and return a (promise of) json-able object so can go through an http request.

The "Omni" part is that it can be integrated for various asynchronous scenarios and in many frameworks.

### Interactive mode

In interactive mode (using `InteractiveServer`), the DB interface contains modification functions and the server exposes modification function, that will modify the DB but also raise events. In this case, an `InteractiveServer` instance has to be created for every client, with an interface toward the DB and a callback for event raising.
Expand All @@ -43,6 +55,7 @@ In interactive mode (using `InteractiveServer`), the DB interface contains modif
Two interfaces allow to implement an interface to any database: `OmnI18n.DB` (who basically just has a `list`) and `OmnI18n.InteractiveDB` who has some modification access

Two are provided: a `MemDB` who is basically an "in-memory database" and its descendant, a `FileDB` who allows:

- reading from a file
- maintaining the files when changes are brought

Expand Down Expand Up @@ -246,13 +259,17 @@ import { reports, type TContext } from "omni18n";
client: I18nClient
}*/

reports.missing = ({key, client}: TContext) {
if (client.loading) return `...` // `onModification` callback has been provided
return `[${key}]`
reports.loading = ({ key, client }: TContext): string {
// report if not expected
return '...'
}
reports.missing = ({ key, client }: TContext, fallback?: string): string {
// report
return fallback ?? `[${key}]`
}
reports.error = (context: TContext, error: string, spec: object) {
if (client.loading) return `...` // `onModification` callback has been provided
return `[!${error}]`
// report
return `[!${error}]`
}
```

Expand All @@ -263,4 +280,4 @@ The function might do as much logging as they wish, the returned string will be
## TODOs

- testing the error system
- detailed documentation on each part
- detailed documentation on each part
12 changes: 12 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# OmnI18n

[Overview](../README.md)

> :warning: **Work in progress!**
Projects using OmnI18n use it in 4 layers

1. [The `client`](./client.md): The client manages the cache and download along with text retrieval and interpolation
2. (optional) The HTTP or any other layer. This part is implemented by the user
3. The `server`: The server exposes functions to interact with the languages
4. The `database`: A class implementing some interface that interacts directly with a database
1 change: 1 addition & 0 deletions docs/_config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
theme: jekyll-theme-leap-day
82 changes: 82 additions & 0 deletions docs/client.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Client part

The client part `I18nClient` is usually instantiated once per client.

For instance, in the browser for an SPA is is instantiated once for the whole web-application lifetime, while on the server-side for SSR, it might be instantiated once per request or per session.

## Interactions and configurations

### With the server

```ts
I18nClient(locales: OmnI18n.Locale[], condense: OmnI18n.Condense, onModification?: OmnI18n.OnModification)
```

- `locales`: A list of locales: from preferred to fallback
- `condense`: A function that will query the server for the condensed dictionary
- `onModification`: A function that will be called when the dictionary is modified

```ts
const client = new I18nClient(['fr', 'en'], server.condense, frontend.refreshTexts)
```

### Global settings

These are variables you can import and modify:

```ts
import { reports, formats, processors } from 'omni18n'
```

#### `reports`

Reporting mechanism in case of problem. They both take an argument of type `TContext` describing mainly the client and the key where the problem occurred

```ts
export interface TContext {
key: string
zones: string[]
client: I18nClient
}
```

> If texts might be displayed before loading is complete, make sure `onModification` has been specified as it will be called when the translations will be provided
These reports will:

- have any side effect, like logging or making a request that will log
- return a string that will be used instead of the expected translation

`reports` contain:

- A missing key report

```ts
reports.missing = ({ key, client }: TContext, fallback?: string) => {
// report
return fallback ?? `[${key}]`
}
```

- A "missing key while loading" report
This one is called only when the client is in a loading state. If `onModification` was specified, it will be called once loaded. If not, the client will automatically check all the keys that went through this error to check them again.

```ts
reports.loading = ({ client }: TContext) => '...'
```

- An interpolation error
When interpolating, an error calls this report with a textual description and some specifications depending on the error.

> The specification is json-able _except_ in the case of `error: "Error in processor"`, in which case `spec.error` is whatever had been thrown and might be an `Error` or `Exception`
```ts
reports.error = ({ key, client }: TContext, error: string, spec: object) => {
// report
return '[!error!]'
}
```

#### `formats`

#### `processors`
7 changes: 7 additions & 0 deletions docs/part2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Part 2

[root](/)

[local root](./)

[index](README.md)
3 changes: 2 additions & 1 deletion jest.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
"^.+\\.(ts|tsx)$": "ts-jest"
},
"testEnvironment": "node",
"moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"]
"moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"],
"coverageReporters": ["lcov"]
}
Loading

0 comments on commit 13c43e4

Please sign in to comment.