├── .gitignore ├── lerna.json ├── package.json ├── packages ├── client │ ├── .editorconfig │ ├── .github │ │ ├── CONTRIBUTING.md │ │ ├── ISSUE_TEMPLATE.md │ │ └── PULL_REQUEST_TEMPLATE.md │ ├── .gitignore │ ├── .npmignore │ ├── .prettierignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── ChainGunClient.ts │ │ ├── ChainGunLink.ts │ │ ├── ControlFlow │ │ │ ├── GunEvent.ts │ │ │ ├── GunProcessQueue.ts │ │ │ ├── GunQueue.ts │ │ │ └── MiddlewareSystem.ts │ │ ├── Graph │ │ │ ├── GunGraph.ts │ │ │ ├── GunGraphNode.ts │ │ │ └── GunGraphUtils.ts │ │ ├── Transports │ │ │ ├── GunGraphConnector.ts │ │ │ ├── GunGraphConnectorFromAdapter.ts │ │ │ ├── GunGraphWireConnector.ts │ │ │ └── WebSocketGraphConnector.ts │ │ ├── index.ts │ │ └── interfaces.ts │ ├── tsconfig.json │ ├── tsconfig.module.json │ └── tslint.json ├── crdt │ ├── .editorconfig │ ├── .github │ │ ├── CONTRIBUTING.md │ │ ├── ISSUE_TEMPLATE.md │ │ └── PULL_REQUEST_TEMPLATE.md │ ├── .gitignore │ ├── .npmignore │ ├── .prettierignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ ├── tsconfig.module.json │ └── tslint.json ├── federation-adapter │ ├── .editorconfig │ ├── .github │ │ ├── CONTRIBUTING.md │ │ ├── ISSUE_TEMPLATE.md │ │ └── PULL_REQUEST_TEMPLATE.md │ ├── .gitignore │ ├── .npmignore │ ├── .prettierignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── FederationAdapter.ts │ │ └── index.ts │ ├── tsconfig.json │ ├── tsconfig.module.json │ └── tslint.json ├── http-adapter │ ├── .editorconfig │ ├── .github │ │ ├── CONTRIBUTING.md │ │ ├── ISSUE_TEMPLATE.md │ │ └── PULL_REQUEST_TEMPLATE.md │ ├── .gitignore │ ├── .npmignore │ ├── .prettierignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── chaingun-http-adapter.ts │ │ └── index.ts │ ├── tsconfig.json │ ├── tsconfig.module.json │ └── tslint.json ├── http-server │ ├── .editorconfig │ ├── .github │ │ ├── CONTRIBUTING.md │ │ ├── ISSUE_TEMPLATE.md │ │ └── PULL_REQUEST_TEMPLATE.md │ ├── .gitignore │ ├── .npmignore │ ├── .prettierignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── chaingun-http-server.ts │ │ └── index.ts │ ├── tsconfig.json │ ├── tsconfig.module.json │ └── tslint.json ├── lmdb-adapter │ ├── .editorconfig │ ├── .gitignore │ ├── .npmignore │ ├── .prettierignore │ ├── .vscode │ │ ├── debug-ts.js │ │ ├── launch.json │ │ └── settings.json │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── chaingun-lmdb-adapter.ts │ │ ├── index.ts │ │ └── types │ │ │ └── node-lmdb.d.ts │ ├── tsconfig.json │ ├── tsconfig.module.json │ └── tslint.json ├── memory-adapter │ ├── .editorconfig │ ├── .github │ │ ├── CONTRIBUTING.md │ │ ├── ISSUE_TEMPLATE.md │ │ └── PULL_REQUEST_TEMPLATE.md │ ├── .gitignore │ ├── .npmignore │ ├── .prettierignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ ├── tsconfig.module.json │ └── tslint.json ├── node-adapters │ ├── .editorconfig │ ├── .github │ │ ├── CONTRIBUTING.md │ │ ├── ISSUE_TEMPLATE.md │ │ └── PULL_REQUEST_TEMPLATE.md │ ├── .gitignore │ ├── .npmignore │ ├── .prettierignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ ├── tsconfig.module.json │ └── tslint.json ├── scope │ ├── .circleci │ │ └── config.yml │ ├── .editorconfig │ ├── .github │ │ ├── CONTRIBUTING.md │ │ ├── ISSUE_TEMPLATE.md │ │ └── PULL_REQUEST_TEMPLATE.md │ ├── .gitignore │ ├── .npmignore │ ├── .prettierignore │ ├── .vscode │ │ ├── debug-ts.js │ │ ├── launch.json │ │ └── settings.json │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── scope.ts │ ├── tsconfig.json │ ├── tsconfig.module.json │ └── tslint.json ├── sea-client │ ├── .editorconfig │ ├── .github │ │ ├── CONTRIBUTING.md │ │ ├── ISSUE_TEMPLATE.md │ │ └── PULL_REQUEST_TEMPLATE.md │ ├── .gitignore │ ├── .npmignore │ ├── .prettierignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── ChainGunSeaClient.ts │ │ ├── ChainGunUserApi.ts │ │ ├── index.ts │ │ └── interfaces.ts │ ├── tsconfig.json │ ├── tsconfig.module.json │ └── tslint.json ├── sear │ ├── .editorconfig │ ├── .github │ │ ├── CONTRIBUTING.md │ │ ├── ISSUE_TEMPLATE.md │ │ └── PULL_REQUEST_TEMPLATE.md │ ├── .gitignore │ ├── .npmignore │ ├── .prettierignore │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── SafeBuffer.ts │ │ ├── SeaArray.ts │ │ ├── authenticate.ts │ │ ├── base64.ts │ │ ├── createUser.ts │ │ ├── decrypt.ts │ │ ├── encrypt.ts │ │ ├── importAesKey.ts │ │ ├── index.ts │ │ ├── interfaces.ts │ │ ├── pair.ts │ │ ├── pseudoRandomText.ts │ │ ├── settings.ts │ │ ├── sha256.ts │ │ ├── shims.ts │ │ ├── sign.ts │ │ ├── soul.ts │ │ ├── unpack.ts │ │ ├── verify.ts │ │ └── work.ts │ ├── tests │ │ ├── encrypt.test.ts │ │ ├── gun-sear.test.ts │ │ └── sign.test.ts │ ├── tsconfig.json │ ├── tsconfig.module.json │ └── tslint.json ├── socketcluster-connector │ ├── .circleci │ │ └── config.yml │ ├── .editorconfig │ ├── .github │ │ ├── CONTRIBUTING.md │ │ ├── ISSUE_TEMPLATE.md │ │ └── PULL_REQUEST_TEMPLATE.md │ ├── .gitignore │ ├── .npmignore │ ├── .prettierignore │ ├── .vscode │ │ ├── debug-ts.js │ │ ├── launch.json │ │ └── settings.json │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── SocketClusterGraphConnector.ts │ │ └── index.ts │ ├── tsconfig.json │ ├── tsconfig.module.json │ └── tslint.json ├── socketcluster-worker │ ├── .circleci │ │ └── config.yml │ ├── .editorconfig │ ├── .github │ │ ├── CONTRIBUTING.md │ │ ├── ISSUE_TEMPLATE.md │ │ └── PULL_REQUEST_TEMPLATE.md │ ├── .gitignore │ ├── .npmignore │ ├── .prettierignore │ ├── .vscode │ │ ├── debug-ts.js │ │ ├── launch.json │ │ └── settings.json │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── ChangelogFeed.ts │ │ ├── GunSocketClusterWorker.ts │ │ ├── config.ts │ │ └── index.ts │ ├── tsconfig.json │ ├── tsconfig.module.json │ └── tslint.json ├── suppressor-sear │ ├── .editorconfig │ ├── .gitignore │ ├── .travis.yml │ ├── LICENSE │ ├── README.md │ ├── code-of-conduct.md │ ├── package.json │ ├── rollup.config.ts │ ├── src │ │ └── @chaingun │ │ │ └── suppressor-sear.ts │ ├── tools │ │ ├── gh-pages-publish.ts │ │ └── semantic-release-prepare.ts │ ├── tsconfig.json │ ├── tslint.json │ └── yarn.lock ├── suppressor │ ├── .editorconfig │ ├── .gitignore │ ├── .travis.yml │ ├── LICENSE │ ├── README.md │ ├── code-of-conduct.md │ ├── package.json │ ├── rollup.config.ts │ ├── src │ │ └── @chaingun │ │ │ └── suppressor.ts │ ├── tools │ │ ├── gh-pages-publish.ts │ │ └── semantic-release-prepare.ts │ ├── tsconfig.json │ ├── tslint.json │ ├── types │ │ └── route-parser.d.ts │ └── yarn.lock └── types │ ├── .editorconfig │ ├── .github │ ├── CONTRIBUTING.md │ ├── ISSUE_TEMPLATE.md │ └── PULL_REQUEST_TEMPLATE.md │ ├── .gitignore │ ├── .npmignore │ ├── .prettierignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ ├── ChainGun.ts │ ├── Gun.ts │ ├── GunGraphAdapter.ts │ └── index.ts │ ├── tsconfig.json │ ├── tsconfig.module.json │ └── tslint.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | test 4 | src/**.js 5 | .idea/* 6 | 7 | .env 8 | coverage 9 | .nyc_output 10 | *.log 11 | 12 | package-lock.json 13 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/*" 4 | ], 5 | "version": "0.23.7" 6 | } 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "buildall": "lerna run build --since" 4 | }, 5 | "private": true, 6 | "workspaces": [ 7 | "packages/*" 8 | ], 9 | "name": "chaingun-workspace", 10 | "devDependencies": { 11 | "husky": "^4.2.1", 12 | "lerna": "^3.20.2" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/client/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | max_line_length = 80 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | max_line_length = 0 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /packages/client/.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Example Contributing Guidelines 2 | 3 | This is an example of GitHub's contributing guidelines file. Check out GitHub's [CONTRIBUTING.md help center article](https://help.github.com/articles/setting-guidelines-for-repository-contributors/) for more information. 4 | -------------------------------------------------------------------------------- /packages/client/.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **I'm submitting a ...** 2 | [ ] bug report 3 | [ ] feature request 4 | [ ] question about the decisions made in the repository 5 | [ ] question about how to use this project 6 | 7 | * **Summary** 8 | 9 | 10 | 11 | * **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.) 12 | -------------------------------------------------------------------------------- /packages/client/.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...) 2 | 3 | 4 | 5 | * **What is the current behavior?** (You can also link to an open issue here) 6 | 7 | 8 | 9 | * **What is the new behavior (if this is a feature change)?** 10 | 11 | 12 | 13 | * **Other information**: 14 | -------------------------------------------------------------------------------- /packages/client/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | test 4 | src/**.js 5 | .idea/* 6 | 7 | coverage 8 | .nyc_output 9 | *.log 10 | 11 | package-lock.json -------------------------------------------------------------------------------- /packages/client/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | tsconfig.json 4 | tsconfig.module.json 5 | tslint.json 6 | .travis.yml 7 | .github 8 | .prettierignore 9 | .vscode 10 | build/docs 11 | **/*.spec.* 12 | coverage 13 | .nyc_output 14 | *.log 15 | -------------------------------------------------------------------------------- /packages/client/.prettierignore: -------------------------------------------------------------------------------- 1 | # package.json is formatted by package managers, so we ignore it here 2 | package.json -------------------------------------------------------------------------------- /packages/client/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 go1dfish 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/client/README.md: -------------------------------------------------------------------------------- 1 | # @chaingun/client 2 | 3 | ChainGun Database Client 4 | -------------------------------------------------------------------------------- /packages/client/src/ChainGunClient.ts: -------------------------------------------------------------------------------- 1 | import { diffGunCRDT } from '@chaingun/crdt' 2 | import { GunMsgCb } from '@chaingun/types' 3 | import { ChainGunLink } from './ChainGunLink' 4 | import { GunGraph } from './Graph/GunGraph' 5 | import { WebSocketGraphConnector } from './Transports/WebSocketGraphConnector' 6 | 7 | interface ChainGunOptions { 8 | readonly peers?: readonly string[] 9 | readonly graph?: GunGraph 10 | readonly WS?: typeof WebSocket 11 | } 12 | 13 | /** 14 | * Main entry point for ChainGun 15 | * 16 | * Usage: 17 | * 18 | * const gun = new ChainGunClient({ peers: ["https://notabug.io/gun"]}) 19 | * gun.get("nab/things/59382d2a08b7d7073415b5b6ae29dfe617690d74").on(thing => console.log(this)) 20 | */ 21 | export class ChainGunClient { 22 | public readonly graph: GunGraph 23 | // tslint:disable-next-line: variable-name readonly-keyword 24 | protected _opt: ChainGunOptions 25 | protected readonly LinkClass: typeof ChainGunLink 26 | 27 | constructor(opt?: ChainGunOptions, LinkClass = ChainGunLink) { 28 | if (opt && opt.graph) { 29 | this.graph = opt.graph 30 | } else { 31 | this.graph = new GunGraph() 32 | this.graph.use(diffGunCRDT) 33 | this.graph.use(diffGunCRDT, 'write') 34 | } 35 | this._opt = {} 36 | if (opt) { 37 | this.opt(opt) 38 | } 39 | 40 | this.LinkClass = LinkClass 41 | } 42 | 43 | /** 44 | * Set ChainGun configuration options 45 | * 46 | * @param options 47 | */ 48 | public opt(options: ChainGunOptions): ChainGunClient { 49 | this._opt = { ...this._opt, ...options } 50 | 51 | if (options.peers) { 52 | options.peers.forEach(peer => { 53 | const connector = new WebSocketGraphConnector(peer, this._opt.WS) 54 | connector.sendPutsFromGraph(this.graph) 55 | connector.sendRequestsFromGraph(this.graph) 56 | this.graph.connect(connector) 57 | }) 58 | } 59 | 60 | return this 61 | } 62 | 63 | /** 64 | * Traverse a location in the graph 65 | * 66 | * @param key Key to read data from 67 | * @param cb 68 | * @returns New chain context corresponding to given key 69 | */ 70 | // tslint:disable-next-line: variable-name 71 | public get(soul: string, _cb?: GunMsgCb): ChainGunLink { 72 | return new this.LinkClass(this, soul) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /packages/client/src/ControlFlow/GunEvent.ts: -------------------------------------------------------------------------------- 1 | type EventCb = (a: T, b?: U, c?: V) => void 2 | 3 | /** 4 | * Generic event/listener system 5 | */ 6 | export class GunEvent { 7 | public readonly name: string 8 | // tslint:disable-next-line: readonly-array readonly-keyword 9 | private _listeners: Array> 10 | 11 | constructor(name = 'GunEvent') { 12 | this.name = name 13 | this._listeners = [] 14 | this.listenerCount = this.listenerCount.bind(this) 15 | this.on = this.on.bind(this) 16 | this.off = this.off.bind(this) 17 | this.trigger = this.trigger.bind(this) 18 | } 19 | 20 | /** 21 | * @returns number of currently subscribed listeners 22 | */ 23 | public listenerCount(): number { 24 | return this._listeners.length 25 | } 26 | 27 | /** 28 | * Register a listener on this event 29 | * 30 | * @param cb the callback to subscribe 31 | */ 32 | public on(cb: EventCb): GunEvent { 33 | if (this._listeners.indexOf(cb) !== -1) { 34 | return this 35 | } 36 | this._listeners.push(cb) 37 | return this 38 | } 39 | 40 | /** 41 | * Unregister a listener on this event 42 | * @param cb the callback to unsubscribe 43 | */ 44 | public off(cb: EventCb): GunEvent { 45 | const idx = this._listeners.indexOf(cb) 46 | if (idx !== -1) { 47 | this._listeners.splice(idx, 1) 48 | } 49 | return this 50 | } 51 | 52 | /** 53 | * Unregister all listeners on this event 54 | */ 55 | public reset(): GunEvent { 56 | this._listeners = [] 57 | return this 58 | } 59 | 60 | /** 61 | * Trigger this event 62 | */ 63 | public trigger(a: T, b?: U, c?: V): GunEvent { 64 | this._listeners.forEach(cb => cb(a, b, c)) 65 | return this 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /packages/client/src/ControlFlow/GunProcessQueue.ts: -------------------------------------------------------------------------------- 1 | import { GunMsg } from '@chaingun/types' 2 | import { GunEvent } from './GunEvent' 3 | import { GunQueue } from './GunQueue' 4 | import { MiddlewareSystem } from './MiddlewareSystem' 5 | 6 | type ProcessDupesOption = 'process_dupes' | 'dont_process_dupes' 7 | 8 | export class GunProcessQueue extends GunQueue { 9 | public readonly middleware: MiddlewareSystem 10 | public readonly isProcessing: boolean 11 | public readonly completed: GunEvent 12 | public readonly emptied: GunEvent 13 | public readonly processDupes: ProcessDupesOption 14 | 15 | // tslint:disable-next-line: readonly-keyword readonly-array 16 | protected alreadyProcessed: T[] 17 | 18 | constructor( 19 | name = 'GunProcessQueue', 20 | processDupes: ProcessDupesOption = 'process_dupes' 21 | ) { 22 | super(name) 23 | this.alreadyProcessed = [] 24 | this.isProcessing = false 25 | this.processDupes = processDupes 26 | this.completed = new GunEvent(`${name}.processed`) 27 | this.emptied = new GunEvent(`${name}.emptied`) 28 | this.middleware = new MiddlewareSystem(`${name}.middleware`) 29 | } 30 | 31 | public has(item: T): boolean { 32 | return super.has(item) || this.alreadyProcessed.indexOf(item) !== -1 33 | } 34 | 35 | public async processNext(b?: U, c?: V): Promise { 36 | // tslint:disable-next-line: no-let 37 | let item = this.dequeue() 38 | const processedItem = item 39 | 40 | if (!item) { 41 | return 42 | } 43 | 44 | item = await this.middleware.process(item, b, c) 45 | 46 | if (processedItem && this.processDupes === 'dont_process_dupes') { 47 | this.alreadyProcessed.push(processedItem) 48 | } 49 | 50 | if (item) { 51 | this.completed.trigger(item) 52 | } 53 | } 54 | 55 | public enqueueMany(items: readonly T[]): GunProcessQueue { 56 | super.enqueueMany(items) 57 | return this 58 | } 59 | 60 | public async process(): Promise { 61 | if (this.isProcessing) { 62 | return 63 | } 64 | 65 | if (!this.count()) { 66 | return 67 | } 68 | 69 | // @ts-ignore 70 | this.isProcessing = true 71 | while (this.count()) { 72 | try { 73 | await this.processNext() 74 | } catch (e) { 75 | // tslint:disable-next-line: no-console 76 | console.error('Process Queue error', e.stack) 77 | } 78 | } 79 | 80 | this.emptied.trigger(true) 81 | 82 | // @ts-ignore 83 | this.isProcessing = false 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /packages/client/src/ControlFlow/GunQueue.ts: -------------------------------------------------------------------------------- 1 | import { GunMsg } from '@chaingun/types' 2 | 3 | export class GunQueue { 4 | public readonly name: string 5 | // tslint:disable-next-line: readonly-keyword readonly-array 6 | private _queue: T[] 7 | 8 | constructor(name = 'GunQueue') { 9 | this.name = name 10 | this._queue = [] 11 | } 12 | 13 | public count(): number { 14 | return this._queue.length 15 | } 16 | 17 | public has(item: T): boolean { 18 | return this._queue.indexOf(item) !== -1 19 | } 20 | 21 | public enqueue(item: T): GunQueue { 22 | if (this.has(item)) { 23 | return this 24 | } 25 | 26 | this._queue.splice(0, 0, item) 27 | return this 28 | } 29 | 30 | public dequeue(): T | undefined { 31 | return this._queue.pop() 32 | } 33 | 34 | public enqueueMany(items: readonly T[]): GunQueue { 35 | const filtered = items.filter(item => !this.has(item)) 36 | 37 | if (filtered.length) { 38 | this._queue.splice(0, 0, ...filtered.slice().reverse()) 39 | } 40 | 41 | return this 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/client/src/ControlFlow/MiddlewareSystem.ts: -------------------------------------------------------------------------------- 1 | export class MiddlewareSystem { 2 | public readonly name: string 3 | // tslint:disable-next-line: readonly-array readonly-keyword 4 | private _middlewareFunctions: Array< 5 | (a: T, b?: U, c?: V) => Promise | T | undefined 6 | > 7 | 8 | constructor(name = 'MiddlewareSystem') { 9 | this.name = name 10 | this._middlewareFunctions = [] 11 | } 12 | 13 | /** 14 | * Register middleware function 15 | * 16 | * @param middleware The middleware function to add 17 | */ 18 | public use( 19 | middleware: (a: T, b?: U, c?: V) => Promise | T | undefined 20 | ): MiddlewareSystem { 21 | if (this._middlewareFunctions.indexOf(middleware) !== -1) { 22 | return this 23 | } 24 | 25 | this._middlewareFunctions.push(middleware) 26 | return this 27 | } 28 | 29 | /** 30 | * Unregister middleware function 31 | * 32 | * @param middleware The middleware function to remove 33 | */ 34 | public unuse( 35 | middleware: (a: T, b?: U, c?: V) => T | undefined 36 | ): MiddlewareSystem { 37 | const idx = this._middlewareFunctions.indexOf(middleware) 38 | if (idx !== -1) { 39 | this._middlewareFunctions.splice(idx, 1) 40 | } 41 | 42 | return this 43 | } 44 | 45 | /** 46 | * Process values through this middleware 47 | * @param a Required, this is the value modified/passed through each middleware fn 48 | * @param b Optional extra argument passed to each middleware function 49 | * @param c Optional extra argument passed to each middleware function 50 | */ 51 | public async process(a: T, b?: U, c?: V): Promise { 52 | // tslint:disable-next-line: no-let 53 | let val: T | undefined = a 54 | 55 | for (const fn of this._middlewareFunctions) { 56 | if (!val) { 57 | return 58 | } 59 | 60 | val = await fn(val, b, c) 61 | } 62 | 63 | return val 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /packages/client/src/Graph/GunGraphNode.ts: -------------------------------------------------------------------------------- 1 | import { GunGraphData, GunMsg, GunNode } from '@chaingun/types' 2 | import { GunEvent } from '../ControlFlow/GunEvent' 3 | import { GunNodeListenCb } from '../interfaces' 4 | import { GunGraph } from './GunGraph' 5 | 6 | /** 7 | * Query state around a single node in the graph 8 | */ 9 | export class GunGraphNode { 10 | public readonly soul: string 11 | 12 | private readonly _data: GunEvent 13 | private readonly _graph: GunGraph 14 | // tslint:disable-next-line: readonly-keyword 15 | private _endCurQuery?: () => void 16 | private readonly _updateGraph: ( 17 | data: GunGraphData, 18 | replyToId?: string 19 | ) => void 20 | 21 | constructor( 22 | graph: GunGraph, 23 | soul: string, 24 | updateGraph: (data: GunGraphData, replyToId?: string) => void 25 | ) { 26 | this._onDirectQueryReply = this._onDirectQueryReply.bind(this) 27 | this._data = new GunEvent(``) 28 | this._graph = graph 29 | this._updateGraph = updateGraph 30 | this.soul = soul 31 | } 32 | 33 | public listenerCount(): number { 34 | return this._data.listenerCount() 35 | } 36 | 37 | public get(cb?: GunNodeListenCb): GunGraphNode { 38 | if (cb) { 39 | this.on(cb) 40 | } 41 | this._ask() 42 | return this 43 | } 44 | 45 | public receive(data: GunNode | undefined): GunGraphNode { 46 | this._data.trigger(data, this.soul) 47 | return this 48 | } 49 | 50 | public on( 51 | cb: (data: GunNode | undefined, soul: string) => void 52 | ): GunGraphNode { 53 | this._data.on(cb) 54 | return this 55 | } 56 | 57 | public off( 58 | cb?: (data: GunNode | undefined, soul: string) => void 59 | ): GunGraphNode { 60 | if (cb) { 61 | this._data.off(cb) 62 | } else { 63 | this._data.reset() 64 | } 65 | 66 | if (this._endCurQuery && !this._data.listenerCount()) { 67 | this._endCurQuery() 68 | this._endCurQuery = undefined 69 | } 70 | 71 | return this 72 | } 73 | 74 | private _ask(): GunGraphNode { 75 | if (this._endCurQuery) { 76 | return this 77 | } 78 | 79 | this._endCurQuery = this._graph.get(this.soul, this._onDirectQueryReply) 80 | return this 81 | } 82 | 83 | private _onDirectQueryReply(msg: GunMsg): void { 84 | if (!msg.put) { 85 | this._updateGraph( 86 | { 87 | [this.soul]: undefined 88 | }, 89 | msg['@'] 90 | ) 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /packages/client/src/Transports/GunGraphConnectorFromAdapter.ts: -------------------------------------------------------------------------------- 1 | import { ChainGunGet, ChainGunPut, GunGraphAdapter } from '@chaingun/types' 2 | import { generateMessageId } from '../Graph/GunGraphUtils' 3 | import { GunGraphWireConnector } from './GunGraphWireConnector' 4 | 5 | // tslint:disable-next-line: no-empty 6 | const NOOP = () => undefined 7 | 8 | export class GunGraphConnectorFromAdapter extends GunGraphWireConnector { 9 | protected readonly adapter: GunGraphAdapter 10 | 11 | constructor(adapter: GunGraphAdapter, name = 'GunGraphConnectorFromAdapter') { 12 | super(name) 13 | this.adapter = adapter 14 | } 15 | 16 | public get({ soul, cb, msgId = '' }: ChainGunGet): () => void { 17 | this.adapter 18 | .get(soul) 19 | .then(node => ({ 20 | '#': generateMessageId(), 21 | '@': msgId, 22 | put: node 23 | ? { 24 | [soul]: node 25 | } 26 | : undefined 27 | })) 28 | .catch(error => { 29 | // tslint:disable-next-line: no-console 30 | console.warn(error.stack || error) 31 | 32 | return { 33 | '#': generateMessageId(), 34 | '@': msgId, 35 | err: 'Error fetching node' 36 | } 37 | }) 38 | .then(msg => { 39 | this.ingest([msg]) 40 | if (cb) { 41 | cb(msg) 42 | } 43 | }) 44 | 45 | return NOOP 46 | } 47 | 48 | public put({ graph, msgId = '', cb }: ChainGunPut): () => void { 49 | this.adapter 50 | .put(graph) 51 | .then(() => { 52 | return { 53 | '#': generateMessageId(), 54 | '@': msgId, 55 | err: null, 56 | ok: true 57 | } 58 | }) 59 | .catch(error => { 60 | // tslint:disable-next-line: no-console 61 | console.warn(error.stack || error) 62 | 63 | return { 64 | '#': generateMessageId(), 65 | '@': msgId, 66 | err: 'Error saving put', 67 | ok: false 68 | } 69 | }) 70 | .then(msg => { 71 | this.ingest([msg]) 72 | if (cb) { 73 | cb(msg) 74 | } 75 | }) 76 | 77 | return NOOP 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /packages/client/src/Transports/GunGraphWireConnector.ts: -------------------------------------------------------------------------------- 1 | import { ChainGunGet, ChainGunPut, GunMsg, GunMsgCb } from '@chaingun/types' 2 | import { generateMessageId } from '../Graph/GunGraphUtils' 3 | import { GunGraphConnector } from './GunGraphConnector' 4 | 5 | export abstract class GunGraphWireConnector extends GunGraphConnector { 6 | private readonly _callbacks: { 7 | readonly [msgId: string]: GunMsgCb 8 | } 9 | 10 | constructor(name = 'GunWireProtocol') { 11 | super(name) 12 | this._callbacks = {} 13 | 14 | this._onProcessedInput = this._onProcessedInput.bind(this) 15 | this.inputQueue.completed.on(this._onProcessedInput) 16 | } 17 | 18 | public off(msgId: string): GunGraphWireConnector { 19 | super.off(msgId) 20 | // @ts-ignore 21 | // tslint:disable-next-line: no-delete 22 | delete this._callbacks[msgId] 23 | return this 24 | } 25 | 26 | /** 27 | * Send graph data for one or more nodes 28 | * 29 | * @returns A function to be called to clean up callback listeners 30 | */ 31 | public put({ graph, msgId = '', replyTo = '', cb }: ChainGunPut): () => void { 32 | if (!graph) { 33 | // tslint:disable-next-line: no-empty 34 | return () => {} 35 | } 36 | const msg: GunMsg = { 37 | put: graph 38 | } 39 | if (msgId) { 40 | // @ts-ignore 41 | msg['#'] = msgId 42 | } 43 | if (replyTo) { 44 | // @ts-ignore 45 | msg['@'] = replyTo 46 | } 47 | 48 | return this.req(msg, cb) 49 | } 50 | 51 | /** 52 | * Request data for a given soul 53 | * 54 | * @returns A function to be called to clean up callback listeners 55 | */ 56 | public get({ soul, cb, msgId = '' }: ChainGunGet): () => void { 57 | const get = { '#': soul } 58 | const msg: GunMsg = { get } 59 | if (msgId) { 60 | // @ts-ignore 61 | msg['#'] = msgId 62 | } 63 | 64 | return this.req(msg, cb) 65 | } 66 | 67 | /** 68 | * Send a message that expects responses via @ 69 | * 70 | * @param msg 71 | * @param cb 72 | */ 73 | public req(msg: GunMsg, cb?: GunMsgCb): () => void { 74 | // @ts-ignore 75 | const reqId = (msg['#'] = msg['#'] || generateMessageId()) 76 | if (cb) { 77 | // @ts-ignore 78 | this._callbacks[reqId] = cb 79 | } 80 | this.send([msg]) 81 | return () => { 82 | this.off(reqId) 83 | } 84 | } 85 | 86 | private _onProcessedInput(msg?: GunMsg): void { 87 | if (!msg) { 88 | return 89 | } 90 | const id = msg['#'] 91 | const replyTo = msg['@'] 92 | 93 | if (msg.put) { 94 | this.events.graphData.trigger(msg.put, id, replyTo) 95 | } 96 | 97 | if (replyTo) { 98 | const cb = this._callbacks[replyTo] 99 | if (cb) { 100 | cb(msg) 101 | } 102 | } 103 | 104 | this.events.receiveMessage.trigger(msg) 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /packages/client/src/Transports/WebSocketGraphConnector.ts: -------------------------------------------------------------------------------- 1 | import { GunMsg } from '@chaingun/types' 2 | import ReconnectingWS from 'reconnecting-websocket' 3 | import { GunGraphWireConnector } from './GunGraphWireConnector' 4 | 5 | export class WebSocketGraphConnector extends GunGraphWireConnector { 6 | public readonly url: string 7 | private readonly _ws: WebSocket 8 | 9 | constructor(url: string, WS = WebSocket) { 10 | super(``) 11 | this.url = url 12 | this.outputQueue.completed.on(this._onOutputProcessed.bind(this)) 13 | this._ws = this._connectWebSocket(WS) 14 | } 15 | 16 | private _connectWebSocket(WS = WebSocket): WebSocket { 17 | const ws = (new ReconnectingWS(this.url.replace(/^http/, 'ws'), [], { 18 | WebSocket: WS 19 | }) as unknown) as WebSocket 20 | 21 | ws.addEventListener('message', this._onReceiveSocketData.bind(this)) 22 | ws.addEventListener('open', () => this.events.connection.trigger(true)) 23 | ws.addEventListener('close', () => this.events.connection.trigger(false)) 24 | 25 | return ws 26 | } 27 | 28 | private _sendToWebsocket(msgs: readonly GunMsg[]): readonly GunMsg[] { 29 | if (!msgs.length) { 30 | return msgs 31 | } 32 | if (msgs.length === 1) { 33 | this._ws.send(JSON.stringify(msgs[0])) 34 | } else if (msgs.length > 0) { 35 | this._ws.send(JSON.stringify(msgs)) 36 | } 37 | return msgs 38 | } 39 | 40 | private _onOutputProcessed(msg?: GunMsg): void { 41 | if (msg) { 42 | this._sendToWebsocket([msg]) 43 | } 44 | } 45 | 46 | private _onReceiveSocketData(msg: MessageEvent): void { 47 | const raw = msg.data 48 | const json = JSON.parse(raw) as GunMsg | ReadonlyArray 49 | 50 | if (Array.isArray(json)) { 51 | this.ingest( 52 | json.map((x: any) => (typeof x === 'string' ? JSON.parse(x) : x)) 53 | ) 54 | } else { 55 | this.ingest([json as GunMsg]) 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /packages/client/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@chaingun/crdt' 2 | export * from '@chaingun/types' 3 | export * from './Graph/GunGraphUtils' 4 | export { ChainGunClient } from './ChainGunClient' 5 | export { GunGraph } from './Graph/GunGraph' 6 | export { ChainGunLink } from './ChainGunLink' 7 | export { GunEvent } from './ControlFlow/GunEvent' 8 | export { GunQueue } from './ControlFlow/GunQueue' 9 | export { GunProcessQueue } from './ControlFlow/GunProcessQueue' 10 | export { GunGraphConnector } from './Transports/GunGraphConnector' 11 | export { GunGraphWireConnector } from './Transports/GunGraphWireConnector' 12 | export { WebSocketGraphConnector } from './Transports/WebSocketGraphConnector' 13 | export { 14 | GunGraphConnectorFromAdapter 15 | } from './Transports/GunGraphConnectorFromAdapter' 16 | -------------------------------------------------------------------------------- /packages/client/src/interfaces.ts: -------------------------------------------------------------------------------- 1 | import { GunGraphData, GunNode, GunValue } from '@chaingun/types' 2 | 3 | export interface GunChainOptions { 4 | readonly uuid?: (path: readonly string[]) => Promise | string 5 | } 6 | export type GunOnCb = (node: GunValue | undefined, key?: string) => void 7 | export type GunNodeListenCb = (node: GunNode | undefined) => void 8 | 9 | export interface PathData { 10 | readonly souls: readonly string[] 11 | readonly value: GunValue | undefined 12 | readonly complete: boolean 13 | } 14 | 15 | export type ChainGunMiddleware = ( 16 | updates: GunGraphData, 17 | existingGraph: GunGraphData 18 | ) => GunGraphData | undefined | Promise 19 | export type ChainGunMiddlewareType = 'read' | 'write' 20 | -------------------------------------------------------------------------------- /packages/client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "outDir": "build/main", 5 | "rootDir": "src", 6 | "moduleResolution": "node", 7 | "module": "commonjs", 8 | "declaration": true, 9 | "inlineSourceMap": true, 10 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, 11 | 12 | "strict": true /* Enable all strict type-checking options. */, 13 | 14 | /* Strict Type-Checking Options */ 15 | // "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, 16 | // "strictNullChecks": true /* Enable strict null checks. */, 17 | // "strictFunctionTypes": true /* Enable strict checking of function types. */, 18 | // "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */, 19 | // "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, 20 | // "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, 21 | 22 | /* Additional Checks */ 23 | "skipLibCheck": true, 24 | "noUnusedLocals": true /* Report errors on unused locals. */, 25 | "noUnusedParameters": true /* Report errors on unused parameters. */, 26 | "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, 27 | "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, 28 | 29 | /* Debugging Options */ 30 | "traceResolution": false /* Report module resolution log messages. */, 31 | "listEmittedFiles": false /* Print names of generated files part of the compilation. */, 32 | "listFiles": false /* Print names of files part of the compilation. */, 33 | "pretty": true /* Stylize errors and messages using color and context. */, 34 | 35 | /* Experimental Options */ 36 | // "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, 37 | // "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, 38 | 39 | "lib": ["es2017", "dom"], 40 | "types": [], 41 | "typeRoots": ["node_modules/@types", "src/types"] 42 | }, 43 | "include": ["src/**/*.ts"], 44 | "exclude": ["node_modules/**"], 45 | "compileOnSave": false 46 | } 47 | -------------------------------------------------------------------------------- /packages/client/tsconfig.module.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "outDir": "build/module", 6 | "module": "esnext" 7 | }, 8 | "exclude": [ 9 | "node_modules/**" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/client/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["tslint:latest", "tslint-config-prettier", "tslint-immutable"], 3 | "rules": { 4 | "interface-name": [true, "never-prefix"], 5 | "variable-name": false, 6 | "no-implicit-dependencies": [true, "dev"], 7 | 8 | "no-var-keyword": true, 9 | "no-parameter-reassignment": true, 10 | "typedef": [true, "call-signature"], 11 | 12 | "readonly-keyword": true, 13 | "readonly-array": true, 14 | "no-let": true, 15 | "no-delete": true, 16 | "no-method-signature": true 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/crdt/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | max_line_length = 80 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | max_line_length = 0 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /packages/crdt/.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Example Contributing Guidelines 2 | 3 | This is an example of GitHub's contributing guidelines file. Check out GitHub's [CONTRIBUTING.md help center article](https://help.github.com/articles/setting-guidelines-for-repository-contributors/) for more information. 4 | -------------------------------------------------------------------------------- /packages/crdt/.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **I'm submitting a ...** 2 | [ ] bug report 3 | [ ] feature request 4 | [ ] question about the decisions made in the repository 5 | [ ] question about how to use this project 6 | 7 | * **Summary** 8 | 9 | 10 | 11 | * **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.) 12 | -------------------------------------------------------------------------------- /packages/crdt/.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...) 2 | 3 | 4 | 5 | * **What is the current behavior?** (You can also link to an open issue here) 6 | 7 | 8 | 9 | * **What is the new behavior (if this is a feature change)?** 10 | 11 | 12 | 13 | * **Other information**: 14 | -------------------------------------------------------------------------------- /packages/crdt/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | test 4 | src/**.js 5 | .idea/* 6 | 7 | coverage 8 | .nyc_output 9 | *.log 10 | 11 | package-lock.json -------------------------------------------------------------------------------- /packages/crdt/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | tsconfig.json 4 | tsconfig.module.json 5 | tslint.json 6 | .travis.yml 7 | .github 8 | .prettierignore 9 | .vscode 10 | build/docs 11 | **/*.spec.* 12 | coverage 13 | .nyc_output 14 | *.log 15 | -------------------------------------------------------------------------------- /packages/crdt/.prettierignore: -------------------------------------------------------------------------------- 1 | # package.json is formatted by package managers, so we ignore it here 2 | package.json -------------------------------------------------------------------------------- /packages/crdt/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 go1dfish 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/crdt/README.md: -------------------------------------------------------------------------------- 1 | # @chaingun/crdt 2 | 3 | Conflict-Free Replicated Data Type functions for ChainGun 4 | -------------------------------------------------------------------------------- /packages/crdt/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "outDir": "build/main", 5 | "rootDir": "src", 6 | "moduleResolution": "node", 7 | "module": "commonjs", 8 | "declaration": true, 9 | "inlineSourceMap": true, 10 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, 11 | 12 | "strict": true /* Enable all strict type-checking options. */, 13 | 14 | /* Strict Type-Checking Options */ 15 | // "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, 16 | // "strictNullChecks": true /* Enable strict null checks. */, 17 | // "strictFunctionTypes": true /* Enable strict checking of function types. */, 18 | // "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */, 19 | // "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, 20 | // "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, 21 | 22 | /* Additional Checks */ 23 | "noUnusedLocals": true /* Report errors on unused locals. */, 24 | "noUnusedParameters": true /* Report errors on unused parameters. */, 25 | "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, 26 | "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, 27 | 28 | /* Debugging Options */ 29 | "traceResolution": false /* Report module resolution log messages. */, 30 | "listEmittedFiles": false /* Print names of generated files part of the compilation. */, 31 | "listFiles": false /* Print names of files part of the compilation. */, 32 | "pretty": true /* Stylize errors and messages using color and context. */, 33 | 34 | /* Experimental Options */ 35 | // "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, 36 | // "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, 37 | 38 | "lib": ["es2017"], 39 | "types": [], 40 | "typeRoots": ["node_modules/@types", "src/types"] 41 | }, 42 | "include": ["src/**/*.ts"], 43 | "exclude": ["node_modules/**"], 44 | "compileOnSave": false 45 | } 46 | -------------------------------------------------------------------------------- /packages/crdt/tsconfig.module.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "outDir": "build/module", 6 | "module": "esnext" 7 | }, 8 | "exclude": [ 9 | "node_modules/**" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/crdt/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["tslint:latest", "tslint-config-prettier", "tslint-immutable"], 3 | "rules": { 4 | "interface-name": [true, "never-prefix"], 5 | "no-implicit-dependencies": [true, "dev"], 6 | 7 | "no-var-keyword": true, 8 | "no-parameter-reassignment": true, 9 | "typedef": [true, "call-signature"], 10 | 11 | "readonly-keyword": true, 12 | "readonly-array": true, 13 | "no-let": true, 14 | "no-object-mutation": true, 15 | "no-delete": true, 16 | "no-method-signature": true, 17 | 18 | "no-this": true, 19 | "no-class": true, 20 | "no-mixed-interface": true, 21 | "no-expression-statement": [ 22 | true, 23 | { "ignore-prefix": ["console.", "process.exit"] } 24 | ] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/federation-adapter/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | max_line_length = 80 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | max_line_length = 0 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /packages/federation-adapter/.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Example Contributing Guidelines 2 | 3 | This is an example of GitHub's contributing guidelines file. Check out GitHub's [CONTRIBUTING.md help center article](https://help.github.com/articles/setting-guidelines-for-repository-contributors/) for more information. 4 | -------------------------------------------------------------------------------- /packages/federation-adapter/.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **I'm submitting a ...** 2 | [ ] bug report 3 | [ ] feature request 4 | [ ] question about the decisions made in the repository 5 | [ ] question about how to use this project 6 | 7 | * **Summary** 8 | 9 | 10 | 11 | * **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.) 12 | -------------------------------------------------------------------------------- /packages/federation-adapter/.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...) 2 | 3 | 4 | 5 | * **What is the current behavior?** (You can also link to an open issue here) 6 | 7 | 8 | 9 | * **What is the new behavior (if this is a feature change)?** 10 | 11 | 12 | 13 | * **Other information**: 14 | -------------------------------------------------------------------------------- /packages/federation-adapter/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | test 4 | src/**.js 5 | .idea/* 6 | 7 | coverage 8 | .nyc_output 9 | *.log 10 | 11 | package-lock.json -------------------------------------------------------------------------------- /packages/federation-adapter/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | tsconfig.json 4 | tsconfig.module.json 5 | tslint.json 6 | .travis.yml 7 | .github 8 | .prettierignore 9 | .vscode 10 | build/docs 11 | **/*.spec.* 12 | coverage 13 | .nyc_output 14 | *.log 15 | -------------------------------------------------------------------------------- /packages/federation-adapter/.prettierignore: -------------------------------------------------------------------------------- 1 | # package.json is formatted by package managers, so we ignore it here 2 | package.json -------------------------------------------------------------------------------- /packages/federation-adapter/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 go1dfish 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/federation-adapter/README.md: -------------------------------------------------------------------------------- 1 | # @chaingun/federation-adapter 2 | 3 | ChainGun Adapter for sourcing from federated peers 4 | -------------------------------------------------------------------------------- /packages/federation-adapter/src/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | FederationAdapter, 3 | FederatedAdapterOpts, 4 | FederatedGunGraphAdapter 5 | } from './FederationAdapter' 6 | -------------------------------------------------------------------------------- /packages/federation-adapter/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "outDir": "build/main", 5 | "rootDir": "src", 6 | "moduleResolution": "node", 7 | "module": "commonjs", 8 | "declaration": true, 9 | "inlineSourceMap": true, 10 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, 11 | 12 | "strict": true /* Enable all strict type-checking options. */, 13 | 14 | /* Strict Type-Checking Options */ 15 | // "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, 16 | // "strictNullChecks": true /* Enable strict null checks. */, 17 | // "strictFunctionTypes": true /* Enable strict checking of function types. */, 18 | // "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */, 19 | // "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, 20 | // "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, 21 | 22 | /* Additional Checks */ 23 | "noUnusedLocals": true /* Report errors on unused locals. */, 24 | "noUnusedParameters": true /* Report errors on unused parameters. */, 25 | "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, 26 | "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, 27 | 28 | /* Debugging Options */ 29 | "traceResolution": false /* Report module resolution log messages. */, 30 | "listEmittedFiles": false /* Print names of generated files part of the compilation. */, 31 | "listFiles": false /* Print names of files part of the compilation. */, 32 | "pretty": true /* Stylize errors and messages using color and context. */, 33 | 34 | /* Experimental Options */ 35 | // "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, 36 | // "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, 37 | 38 | "lib": ["es2017", "dom"], 39 | "types": ["node"], 40 | "typeRoots": ["node_modules/@types", "src/types"] 41 | }, 42 | "include": ["src/**/*.ts"], 43 | "exclude": ["node_modules/**"], 44 | "compileOnSave": false 45 | } 46 | -------------------------------------------------------------------------------- /packages/federation-adapter/tsconfig.module.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "outDir": "build/module", 6 | "module": "esnext" 7 | }, 8 | "exclude": [ 9 | "node_modules/**" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/federation-adapter/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["tslint:latest", "tslint-config-prettier", "tslint-immutable"], 3 | "rules": { 4 | "interface-name": [true, "never-prefix"], 5 | // TODO: allow devDependencies only in **/*.spec.ts files: 6 | // waiting on https://github.com/palantir/tslint/pull/3708 7 | "no-implicit-dependencies": [true, "dev"], 8 | 9 | /* tslint-immutable rules */ 10 | // Recommended built-in rules 11 | "no-var-keyword": true, 12 | "no-parameter-reassignment": true, 13 | "typedef": [true, "call-signature"], 14 | 15 | // Immutability rules 16 | "readonly-keyword": true, 17 | "readonly-array": true, 18 | "no-let": true, 19 | "no-object-mutation": true, 20 | "no-delete": true, 21 | "no-method-signature": true, 22 | 23 | // Functional style rules 24 | "no-this": true, 25 | "no-class": true, 26 | "no-mixed-interface": true 27 | /* end tslint-immutable rules */ 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/http-adapter/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | max_line_length = 80 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | max_line_length = 0 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /packages/http-adapter/.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Example Contributing Guidelines 2 | 3 | This is an example of GitHub's contributing guidelines file. Check out GitHub's [CONTRIBUTING.md help center article](https://help.github.com/articles/setting-guidelines-for-repository-contributors/) for more information. 4 | -------------------------------------------------------------------------------- /packages/http-adapter/.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **I'm submitting a ...** 2 | [ ] bug report 3 | [ ] feature request 4 | [ ] question about the decisions made in the repository 5 | [ ] question about how to use this project 6 | 7 | * **Summary** 8 | 9 | 10 | 11 | * **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.) 12 | -------------------------------------------------------------------------------- /packages/http-adapter/.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...) 2 | 3 | 4 | 5 | * **What is the current behavior?** (You can also link to an open issue here) 6 | 7 | 8 | 9 | * **What is the new behavior (if this is a feature change)?** 10 | 11 | 12 | 13 | * **Other information**: 14 | -------------------------------------------------------------------------------- /packages/http-adapter/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | test 4 | src/**.js 5 | .idea/* 6 | 7 | coverage 8 | .nyc_output 9 | *.log 10 | 11 | package-lock.json -------------------------------------------------------------------------------- /packages/http-adapter/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | tsconfig.json 4 | tsconfig.module.json 5 | tslint.json 6 | .travis.yml 7 | .github 8 | .prettierignore 9 | .vscode 10 | build/docs 11 | **/*.spec.* 12 | coverage 13 | .nyc_output 14 | *.log 15 | -------------------------------------------------------------------------------- /packages/http-adapter/.prettierignore: -------------------------------------------------------------------------------- 1 | # package.json is formatted by package managers, so we ignore it here 2 | package.json -------------------------------------------------------------------------------- /packages/http-adapter/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 go1dfish 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/http-adapter/README.md: -------------------------------------------------------------------------------- 1 | # @chaingun/http-adapter 2 | 3 | HTTP Graph Adapter for ChainGun 4 | -------------------------------------------------------------------------------- /packages/http-adapter/src/chaingun-http-adapter.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ChangeSetEntry, 3 | GunGetOpts, 4 | GunGraphAdapter, 5 | GunGraphData, 6 | GunNode 7 | } from '@chaingun/types'; 8 | import EventSource from 'eventsource'; 9 | import 'isomorphic-fetch'; 10 | 11 | const BASE_HEADERS = { 12 | Accept: 'application/json', 13 | 'Content-Type': 'application/json' 14 | }; 15 | 16 | export function createGraphAdapter( 17 | baseUrl: string, 18 | fetchOpts: any = {} 19 | ): GunGraphAdapter { 20 | return { 21 | get: (soul: string, opts?: GunGetOpts) => 22 | get(fetchOpts, baseUrl, soul, opts), 23 | onChange: (handler: (change: ChangeSetEntry) => void, from?: string) => 24 | onChange(baseUrl, handler, from), 25 | put: (graphData: GunGraphData) => put(fetchOpts, baseUrl, graphData) 26 | }; 27 | } 28 | 29 | export async function get( 30 | fetchOpts: any, 31 | baseUrl: string, 32 | soul: string, 33 | opts?: GunGetOpts 34 | ): Promise { 35 | const singleKey = opts && opts['.']; 36 | const fromLex = opts && opts['>']; 37 | const toLex = opts && opts['<']; 38 | 39 | const url = singleKey 40 | ? `${baseUrl}/key/${encodeURI(singleKey)}/from_node/${encodeURI(soul)}` 41 | : fromLex && toLex 42 | ? `${baseUrl}/keys/from/${encodeURI(fromLex)}/to/${encodeURI( 43 | toLex 44 | )}/from_node/${encodeURI(soul)}` 45 | : fromLex 46 | ? `${baseUrl}/keys/from/${encodeURI(fromLex)}/from_node/${encodeURI(soul)}` 47 | : toLex 48 | ? `${baseUrl}/keys/to/${encodeURI(toLex)}/from_node/${encodeURI(soul)}` 49 | : `${baseUrl}/nodes/${encodeURI(soul)}`; 50 | const response = await fetch(url, fetchOpts); 51 | 52 | if (response.status === 404) { 53 | return null; 54 | } 55 | 56 | if (response.status >= 400) { 57 | throw new Error('Bad response from server: ' + response.status); 58 | } 59 | 60 | const json = await response.json(); 61 | 62 | if (!json) { 63 | return null; 64 | } 65 | 66 | return json; 67 | } 68 | 69 | export async function put( 70 | fetchOpts: any, 71 | baseUrl: string, 72 | data: GunGraphData 73 | ): Promise { 74 | const url = `${baseUrl}/nodes`; 75 | const response = await fetch(url, { 76 | headers: BASE_HEADERS, 77 | ...fetchOpts, 78 | body: JSON.stringify(data), 79 | method: 'PUT' 80 | }); 81 | 82 | if (response.status >= 400) { 83 | throw new Error('Bad response from server: ' + response.status); 84 | } 85 | 86 | const json = await response.json(); 87 | return json || null; 88 | } 89 | 90 | export function onChange( 91 | baseUrl: string, 92 | handler: (change: ChangeSetEntry) => void, 93 | from: string = '' 94 | ): () => void { 95 | const es = new EventSource(`${baseUrl}/changelog?lastId=${from}`); 96 | 97 | // tslint:disable-next-line: no-object-mutation no-expression-statement 98 | es.onmessage = e => { 99 | const { data, lastEventId } = e; 100 | 101 | // tslint:disable-next-line: no-expression-statement 102 | handler([lastEventId, JSON.parse(data)]); 103 | }; 104 | 105 | return () => es.close(); 106 | } 107 | -------------------------------------------------------------------------------- /packages/http-adapter/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './chaingun-http-adapter'; 2 | -------------------------------------------------------------------------------- /packages/http-adapter/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "outDir": "build/main", 5 | "rootDir": "src", 6 | "moduleResolution": "node", 7 | "module": "commonjs", 8 | "declaration": true, 9 | "inlineSourceMap": true, 10 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, 11 | 12 | "strict": true /* Enable all strict type-checking options. */, 13 | 14 | /* Strict Type-Checking Options */ 15 | // "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, 16 | // "strictNullChecks": true /* Enable strict null checks. */, 17 | // "strictFunctionTypes": true /* Enable strict checking of function types. */, 18 | // "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */, 19 | // "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, 20 | // "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, 21 | 22 | /* Additional Checks */ 23 | "noUnusedLocals": true /* Report errors on unused locals. */, 24 | "noUnusedParameters": true /* Report errors on unused parameters. */, 25 | "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, 26 | "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, 27 | 28 | /* Debugging Options */ 29 | "traceResolution": false /* Report module resolution log messages. */, 30 | "listEmittedFiles": false /* Print names of generated files part of the compilation. */, 31 | "listFiles": false /* Print names of files part of the compilation. */, 32 | "pretty": true /* Stylize errors and messages using color and context. */, 33 | 34 | /* Experimental Options */ 35 | // "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, 36 | // "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, 37 | 38 | "lib": ["es2017", "dom"], 39 | "types": [], 40 | "typeRoots": ["node_modules/@types", "src/types"] 41 | }, 42 | "include": ["src/**/*.ts"], 43 | "exclude": ["node_modules/**"], 44 | "compileOnSave": false 45 | } 46 | -------------------------------------------------------------------------------- /packages/http-adapter/tsconfig.module.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "outDir": "build/module", 6 | "module": "esnext" 7 | }, 8 | "exclude": [ 9 | "node_modules/**" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/http-adapter/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["tslint:latest", "tslint-config-prettier", "tslint-immutable"], 3 | "rules": { 4 | "interface-name": [true, "never-prefix"], 5 | "no-implicit-dependencies": [true, "dev"], 6 | 7 | "no-var-keyword": true, 8 | "no-parameter-reassignment": true, 9 | "typedef": [true, "call-signature"], 10 | 11 | "readonly-keyword": true, 12 | "readonly-array": true, 13 | "no-let": true, 14 | "no-object-mutation": true, 15 | "no-delete": true, 16 | "no-method-signature": true, 17 | 18 | "no-this": true, 19 | "no-class": true, 20 | "no-mixed-interface": true, 21 | "no-expression-statement": [ 22 | true, 23 | { "ignore-prefix": ["console.", "process.exit"] } 24 | ] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/http-server/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | max_line_length = 80 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | max_line_length = 0 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /packages/http-server/.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Example Contributing Guidelines 2 | 3 | This is an example of GitHub's contributing guidelines file. Check out GitHub's [CONTRIBUTING.md help center article](https://help.github.com/articles/setting-guidelines-for-repository-contributors/) for more information. 4 | -------------------------------------------------------------------------------- /packages/http-server/.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **I'm submitting a ...** 2 | [ ] bug report 3 | [ ] feature request 4 | [ ] question about the decisions made in the repository 5 | [ ] question about how to use this project 6 | 7 | * **Summary** 8 | 9 | 10 | 11 | * **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.) 12 | -------------------------------------------------------------------------------- /packages/http-server/.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...) 2 | 3 | 4 | 5 | * **What is the current behavior?** (You can also link to an open issue here) 6 | 7 | 8 | 9 | * **What is the new behavior (if this is a feature change)?** 10 | 11 | 12 | 13 | * **Other information**: 14 | -------------------------------------------------------------------------------- /packages/http-server/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | test 4 | src/**.js 5 | .idea/* 6 | 7 | coverage 8 | .nyc_output 9 | *.log 10 | 11 | package-lock.json -------------------------------------------------------------------------------- /packages/http-server/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | tsconfig.json 4 | tsconfig.module.json 5 | tslint.json 6 | .travis.yml 7 | .github 8 | .prettierignore 9 | .vscode 10 | build/docs 11 | **/*.spec.* 12 | coverage 13 | .nyc_output 14 | *.log 15 | -------------------------------------------------------------------------------- /packages/http-server/.prettierignore: -------------------------------------------------------------------------------- 1 | # package.json is formatted by package managers, so we ignore it here 2 | package.json -------------------------------------------------------------------------------- /packages/http-server/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 go1dfish 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/http-server/README.md: -------------------------------------------------------------------------------- 1 | # @chaingun/http-server 2 | 3 | HTTP Server for ChainGun DB 4 | -------------------------------------------------------------------------------- /packages/http-server/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './chaingun-http-server' 2 | -------------------------------------------------------------------------------- /packages/http-server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "outDir": "build/main", 5 | "rootDir": "src", 6 | "moduleResolution": "node", 7 | "module": "commonjs", 8 | "declaration": true, 9 | "inlineSourceMap": true, 10 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, 11 | 12 | "strict": true /* Enable all strict type-checking options. */, 13 | 14 | /* Strict Type-Checking Options */ 15 | // "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, 16 | // "strictNullChecks": true /* Enable strict null checks. */, 17 | // "strictFunctionTypes": true /* Enable strict checking of function types. */, 18 | // "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */, 19 | // "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, 20 | // "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, 21 | 22 | /* Additional Checks */ 23 | "noUnusedLocals": true /* Report errors on unused locals. */, 24 | "noUnusedParameters": true /* Report errors on unused parameters. */, 25 | "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, 26 | "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, 27 | 28 | /* Debugging Options */ 29 | "traceResolution": false /* Report module resolution log messages. */, 30 | "listEmittedFiles": false /* Print names of generated files part of the compilation. */, 31 | "listFiles": false /* Print names of files part of the compilation. */, 32 | "pretty": true /* Stylize errors and messages using color and context. */, 33 | 34 | /* Experimental Options */ 35 | // "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, 36 | // "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, 37 | 38 | "lib": ["es2017"], 39 | "types": ["node"], 40 | "typeRoots": ["node_modules/@types", "src/types"] 41 | }, 42 | "include": ["src/**/*.ts"], 43 | "exclude": ["node_modules/**"], 44 | "compileOnSave": false 45 | } 46 | -------------------------------------------------------------------------------- /packages/http-server/tsconfig.module.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "outDir": "build/module", 6 | "module": "esnext" 7 | }, 8 | "exclude": [ 9 | "node_modules/**" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/http-server/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["tslint:latest", "tslint-config-prettier", "tslint-immutable"], 3 | "rules": { 4 | "interface-name": [true, "never-prefix"], 5 | "no-implicit-dependencies": [true, "dev"], 6 | 7 | "no-var-keyword": true, 8 | "no-parameter-reassignment": true, 9 | "typedef": [true, "call-signature"], 10 | 11 | "readonly-keyword": true, 12 | "readonly-array": true, 13 | "no-let": true, 14 | "no-object-mutation": true, 15 | "no-delete": true, 16 | "no-method-signature": true, 17 | 18 | "no-this": true, 19 | "no-class": true, 20 | "no-mixed-interface": true 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/lmdb-adapter/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | max_line_length = 80 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | max_line_length = 0 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /packages/lmdb-adapter/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | test 4 | src/**.js 5 | .idea/* 6 | 7 | coverage 8 | .nyc_output 9 | *.log 10 | 11 | package-lock.json -------------------------------------------------------------------------------- /packages/lmdb-adapter/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | tsconfig.json 4 | tsconfig.module.json 5 | tslint.json 6 | .travis.yml 7 | .github 8 | .prettierignore 9 | .vscode 10 | build/docs 11 | **/*.spec.* 12 | coverage 13 | .nyc_output 14 | *.log 15 | -------------------------------------------------------------------------------- /packages/lmdb-adapter/.prettierignore: -------------------------------------------------------------------------------- 1 | # package.json is formatted by package managers, so we ignore it here 2 | package.json -------------------------------------------------------------------------------- /packages/lmdb-adapter/.vscode/debug-ts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const meow = require('meow'); 3 | const path = require('path'); 4 | 5 | const tsFile = getTSFile(); 6 | const jsFile = TS2JS(tsFile); 7 | 8 | replaceCLIArg(tsFile, jsFile); 9 | 10 | // Ava debugger 11 | require('ava/profile'); 12 | 13 | /** 14 | * get ts file path from CLI args 15 | * 16 | * @return string path 17 | */ 18 | function getTSFile() { 19 | const cli = meow(); 20 | return cli.input[0]; 21 | } 22 | 23 | /** 24 | * get associated compiled js file path 25 | * 26 | * @param tsFile path 27 | * @return string path 28 | */ 29 | function TS2JS(tsFile) { 30 | const srcFolder = path.join(__dirname, '..', 'src'); 31 | const distFolder = path.join(__dirname, '..', 'build', 'main'); 32 | 33 | const tsPathObj = path.parse(tsFile); 34 | 35 | return path.format({ 36 | dir: tsPathObj.dir.replace(srcFolder, distFolder), 37 | ext: '.js', 38 | name: tsPathObj.name, 39 | root: tsPathObj.root 40 | }); 41 | } 42 | 43 | /** 44 | * replace a value in CLI args 45 | * 46 | * @param search value to search 47 | * @param replace value to replace 48 | * @return void 49 | */ 50 | function replaceCLIArg(search, replace) { 51 | process.argv[process.argv.indexOf(search)] = replace; 52 | } -------------------------------------------------------------------------------- /packages/lmdb-adapter/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [{ 4 | "type": "node", 5 | "request": "launch", 6 | "name": "Debug Project", 7 | // we test in `build` to make cleanup fast and easy 8 | "cwd": "${workspaceFolder}/build", 9 | // Replace this with your project root. If there are multiple, you can 10 | // automatically run the currently visible file with: "program": ${file}" 11 | "program": "${workspaceFolder}/src/cli/cli.ts", 12 | // "args": ["--no-install"], 13 | "outFiles": ["${workspaceFolder}/build/main/**/*.js"], 14 | "skipFiles": [ 15 | "/**/*.js", 16 | "${workspaceFolder}/node_modules/**/*.js" 17 | ], 18 | "preLaunchTask": "npm: build", 19 | "stopOnEntry": true, 20 | "smartStep": true, 21 | "runtimeArgs": ["--nolazy"], 22 | "env": { 23 | "TYPESCRIPT_STARTER_REPO_URL": "${workspaceFolder}" 24 | }, 25 | "console": "externalTerminal" 26 | }, 27 | { 28 | "type": "node", 29 | "request": "launch", 30 | "name": "Debug Spec", 31 | "program": "${workspaceRoot}/.vscode/debug-ts.js", 32 | "args": ["${file}"], 33 | "skipFiles": ["/**/*.js"], 34 | // Consider using `npm run watch` or `yarn watch` for faster debugging 35 | // "preLaunchTask": "npm: build", 36 | // "smartStep": true, 37 | "runtimeArgs": ["--nolazy"] 38 | }] 39 | } -------------------------------------------------------------------------------- /packages/lmdb-adapter/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib" 3 | // "typescript.implementationsCodeLens.enabled": true 4 | // "typescript.referencesCodeLens.enabled": true 5 | } 6 | -------------------------------------------------------------------------------- /packages/lmdb-adapter/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 go1dfish 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/lmdb-adapter/README.md: -------------------------------------------------------------------------------- 1 | # gun-graph-adapter-lmdb 2 | 3 | Standard Gun Graph Adapter interface for LMDB 4 | -------------------------------------------------------------------------------- /packages/lmdb-adapter/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './chaingun-lmdb-adapter' 2 | -------------------------------------------------------------------------------- /packages/lmdb-adapter/src/types/node-lmdb.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'node-lmdb' { 2 | export class Cursor { 3 | constructor(txn: any, dby: any) 4 | close(): any 5 | del(): any 6 | getCurrentBinary(): any 7 | getCurrentBinaryUnsafe(): any 8 | getCurrentBoolean(): any 9 | getCurrentNumber(): any 10 | getCurrentString(): string | undefined 11 | getCurrentStringUnsafe(): string | undefined 12 | goToDup(): string | undefined 13 | goToDupRange(): string | undefined 14 | goToFirst(): string | undefined 15 | goToFirstDup(): string | undefined 16 | goToKey(key: string): string | undefined 17 | goToLast(): string | undefined 18 | goToLastDup(): string | undefined 19 | goToNext(): string | undefined 20 | goToNextDup(): string | undefined 21 | goToPrev(): string | undefined 22 | goToPrevDup(): string | undefined 23 | goToRange(key: string): string | undefined 24 | } 25 | export class Env { 26 | beginTxn(): any 27 | close(): any 28 | info(): any 29 | open(opts: any): any 30 | openDbi(opts?: any): any 31 | resize(): any 32 | stat(): any 33 | sync(): any 34 | } 35 | export const path: string 36 | export const version: { 37 | major: number 38 | minor: number 39 | patch: number 40 | versionString: string 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/lmdb-adapter/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "outDir": "build/main", 5 | "rootDir": "src", 6 | "moduleResolution": "node", 7 | "module": "commonjs", 8 | "declaration": true, 9 | "inlineSourceMap": true, 10 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, 11 | 12 | "strict": true /* Enable all strict type-checking options. */, 13 | 14 | /* Strict Type-Checking Options */ 15 | // "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, 16 | // "strictNullChecks": true /* Enable strict null checks. */, 17 | // "strictFunctionTypes": true /* Enable strict checking of function types. */, 18 | // "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */, 19 | // "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, 20 | // "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, 21 | 22 | /* Additional Checks */ 23 | "noUnusedLocals": true /* Report errors on unused locals. */, 24 | "noUnusedParameters": true /* Report errors on unused parameters. */, 25 | "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, 26 | "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, 27 | 28 | /* Debugging Options */ 29 | "traceResolution": false /* Report module resolution log messages. */, 30 | "listEmittedFiles": false /* Print names of generated files part of the compilation. */, 31 | "listFiles": false /* Print names of files part of the compilation. */, 32 | "pretty": true /* Stylize errors and messages using color and context. */, 33 | 34 | /* Experimental Options */ 35 | // "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, 36 | // "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, 37 | 38 | "lib": ["es2017"], 39 | "types": ["node"], 40 | "typeRoots": ["node_modules/@types", "src/types"] 41 | }, 42 | "include": ["src/**/*.ts"], 43 | "exclude": ["node_modules/**"], 44 | "compileOnSave": false 45 | } 46 | -------------------------------------------------------------------------------- /packages/lmdb-adapter/tsconfig.module.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "outDir": "build/module", 6 | "module": "esnext" 7 | }, 8 | "exclude": [ 9 | "node_modules/**" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/lmdb-adapter/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["tslint:latest", "tslint-config-prettier", "tslint-immutable"], 3 | "rules": { 4 | "interface-name": [true, "never-prefix"], 5 | "no-implicit-dependencies": [true, "dev"], 6 | 7 | "no-var-keyword": true, 8 | "no-parameter-reassignment": true, 9 | "typedef": [true, "call-signature"], 10 | 11 | "readonly-keyword": true, 12 | "readonly-array": true, 13 | "no-let": true, 14 | "no-object-mutation": true, 15 | "no-delete": true, 16 | "no-method-signature": true, 17 | 18 | "no-this": true, 19 | "no-class": true, 20 | "no-mixed-interface": true 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/memory-adapter/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | max_line_length = 80 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | max_line_length = 0 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /packages/memory-adapter/.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Example Contributing Guidelines 2 | 3 | This is an example of GitHub's contributing guidelines file. Check out GitHub's [CONTRIBUTING.md help center article](https://help.github.com/articles/setting-guidelines-for-repository-contributors/) for more information. 4 | -------------------------------------------------------------------------------- /packages/memory-adapter/.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **I'm submitting a ...** 2 | [ ] bug report 3 | [ ] feature request 4 | [ ] question about the decisions made in the repository 5 | [ ] question about how to use this project 6 | 7 | * **Summary** 8 | 9 | 10 | 11 | * **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.) 12 | -------------------------------------------------------------------------------- /packages/memory-adapter/.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...) 2 | 3 | 4 | 5 | * **What is the current behavior?** (You can also link to an open issue here) 6 | 7 | 8 | 9 | * **What is the new behavior (if this is a feature change)?** 10 | 11 | 12 | 13 | * **Other information**: 14 | -------------------------------------------------------------------------------- /packages/memory-adapter/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | test 4 | src/**.js 5 | .idea/* 6 | 7 | coverage 8 | .nyc_output 9 | *.log 10 | 11 | package-lock.json -------------------------------------------------------------------------------- /packages/memory-adapter/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | tsconfig.json 4 | tsconfig.module.json 5 | tslint.json 6 | .travis.yml 7 | .github 8 | .prettierignore 9 | .vscode 10 | build/docs 11 | **/*.spec.* 12 | coverage 13 | .nyc_output 14 | *.log 15 | -------------------------------------------------------------------------------- /packages/memory-adapter/.prettierignore: -------------------------------------------------------------------------------- 1 | # package.json is formatted by package managers, so we ignore it here 2 | package.json -------------------------------------------------------------------------------- /packages/memory-adapter/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 go1dfish 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/memory-adapter/README.md: -------------------------------------------------------------------------------- 1 | # @chaingun/memory-adapter 2 | 3 | In Memory graph adapter for chaingun 4 | -------------------------------------------------------------------------------- /packages/memory-adapter/src/index.ts: -------------------------------------------------------------------------------- 1 | import { diffGunCRDT, mergeGraph } from '@chaingun/crdt' 2 | import { GunGraphAdapter, GunGraphData, GunNode } from '@chaingun/types' 3 | import { clone, curry } from 'ramda' 4 | 5 | const DEFAULT_OPTS = { 6 | diffFn: diffGunCRDT, 7 | mergeFn: mergeGraph 8 | } 9 | 10 | interface MemoryAdapterOpts { 11 | readonly diffFn?: typeof diffGunCRDT 12 | readonly mergeFn?: typeof mergeGraph 13 | readonly direct?: boolean 14 | } 15 | 16 | const getSync = curry( 17 | ( 18 | // tslint:disable-next-line: variable-name 19 | opts: MemoryAdapterOpts, 20 | graph: GunGraphData, 21 | soul: string 22 | ): GunNode | null => (opts.direct ? graph[soul] : clone(graph[soul])) || null 23 | ) 24 | 25 | const get = curry( 26 | ( 27 | opts: MemoryAdapterOpts, 28 | graph: GunGraphData, 29 | soul: string 30 | ): Promise => Promise.resolve(getSync(opts, graph, soul)) 31 | ) 32 | 33 | const putSync = curry( 34 | ( 35 | // tslint:disable-next-line: variable-name 36 | { 37 | diffFn = DEFAULT_OPTS.diffFn, 38 | mergeFn = DEFAULT_OPTS.mergeFn 39 | }: MemoryAdapterOpts, 40 | graph: GunGraphData, 41 | graphData: GunGraphData 42 | ) => { 43 | const diff = diffFn(graphData, graph) 44 | 45 | if (diff) { 46 | // tslint:disable-next-line: no-expression-statement 47 | mergeFn(graph, diff, 'mutable') 48 | } 49 | 50 | return diff || null 51 | } 52 | ) 53 | 54 | const put = curry( 55 | ( 56 | opts: MemoryAdapterOpts, 57 | graph: GunGraphData, 58 | graphData: GunGraphData 59 | ): Promise => 60 | Promise.resolve(putSync(opts, graph, graphData)) 61 | ) 62 | 63 | export function createMemoryAdapter( 64 | opts: MemoryAdapterOpts = DEFAULT_OPTS 65 | ): GunGraphAdapter { 66 | const graph: GunGraphData = {} 67 | 68 | return { 69 | get: get(opts, graph), 70 | getSync: getSync(opts, graph), 71 | put: put(opts, graph), 72 | putSync: putSync(opts, graph) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /packages/memory-adapter/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "outDir": "build/main", 5 | "rootDir": "src", 6 | "moduleResolution": "node", 7 | "module": "commonjs", 8 | "declaration": true, 9 | "inlineSourceMap": true, 10 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, 11 | 12 | "strict": true /* Enable all strict type-checking options. */, 13 | 14 | /* Strict Type-Checking Options */ 15 | // "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, 16 | // "strictNullChecks": true /* Enable strict null checks. */, 17 | // "strictFunctionTypes": true /* Enable strict checking of function types. */, 18 | // "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */, 19 | // "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, 20 | // "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, 21 | 22 | /* Additional Checks */ 23 | "noUnusedLocals": true /* Report errors on unused locals. */, 24 | "noUnusedParameters": true /* Report errors on unused parameters. */, 25 | "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, 26 | "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, 27 | 28 | /* Debugging Options */ 29 | "traceResolution": false /* Report module resolution log messages. */, 30 | "listEmittedFiles": false /* Print names of generated files part of the compilation. */, 31 | "listFiles": false /* Print names of files part of the compilation. */, 32 | "pretty": true /* Stylize errors and messages using color and context. */, 33 | 34 | /* Experimental Options */ 35 | // "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, 36 | // "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, 37 | 38 | "lib": ["es2017"], 39 | "types": [], 40 | "typeRoots": ["node_modules/@types", "src/types"] 41 | }, 42 | "include": ["src/**/*.ts"], 43 | "exclude": ["node_modules/**"], 44 | "compileOnSave": false 45 | } 46 | -------------------------------------------------------------------------------- /packages/memory-adapter/tsconfig.module.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "outDir": "build/module", 6 | "module": "esnext" 7 | }, 8 | "exclude": [ 9 | "node_modules/**" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/memory-adapter/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["tslint:latest", "tslint-config-prettier", "tslint-immutable"], 3 | "rules": { 4 | "interface-name": [true, "never-prefix"], 5 | "no-implicit-dependencies": [true, "dev"], 6 | 7 | "no-var-keyword": true, 8 | "no-parameter-reassignment": true, 9 | "typedef": [true, "call-signature"], 10 | 11 | "readonly-keyword": true, 12 | "readonly-array": true, 13 | "no-let": true, 14 | "no-object-mutation": true, 15 | "no-delete": true, 16 | "no-method-signature": true, 17 | 18 | "no-this": true, 19 | "no-class": true, 20 | "no-mixed-interface": true, 21 | "no-expression-statement": [ 22 | true, 23 | { "ignore-prefix": ["console.", "process.exit"] } 24 | ] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/node-adapters/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | max_line_length = 80 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | max_line_length = 0 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /packages/node-adapters/.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Example Contributing Guidelines 2 | 3 | This is an example of GitHub's contributing guidelines file. Check out GitHub's [CONTRIBUTING.md help center article](https://help.github.com/articles/setting-guidelines-for-repository-contributors/) for more information. 4 | -------------------------------------------------------------------------------- /packages/node-adapters/.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **I'm submitting a ...** 2 | [ ] bug report 3 | [ ] feature request 4 | [ ] question about the decisions made in the repository 5 | [ ] question about how to use this project 6 | 7 | * **Summary** 8 | 9 | 10 | 11 | * **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.) 12 | -------------------------------------------------------------------------------- /packages/node-adapters/.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...) 2 | 3 | 4 | 5 | * **What is the current behavior?** (You can also link to an open issue here) 6 | 7 | 8 | 9 | * **What is the new behavior (if this is a feature change)?** 10 | 11 | 12 | 13 | * **Other information**: 14 | -------------------------------------------------------------------------------- /packages/node-adapters/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | test 4 | src/**.js 5 | .idea/* 6 | 7 | coverage 8 | .nyc_output 9 | *.log 10 | 11 | package-lock.json -------------------------------------------------------------------------------- /packages/node-adapters/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | tsconfig.json 4 | tsconfig.module.json 5 | tslint.json 6 | .travis.yml 7 | .github 8 | .prettierignore 9 | .vscode 10 | build/docs 11 | **/*.spec.* 12 | coverage 13 | .nyc_output 14 | *.log 15 | -------------------------------------------------------------------------------- /packages/node-adapters/.prettierignore: -------------------------------------------------------------------------------- 1 | # package.json is formatted by package managers, so we ignore it here 2 | package.json -------------------------------------------------------------------------------- /packages/node-adapters/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 go1dfish 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/node-adapters/README.md: -------------------------------------------------------------------------------- 1 | # @chaingun/adapters 2 | 3 | Meta-Package for selecting adapter based on env 4 | -------------------------------------------------------------------------------- /packages/node-adapters/src/index.ts: -------------------------------------------------------------------------------- 1 | import { GunGraphAdapter } from '@chaingun/types' 2 | 3 | export default function createAdapter(): GunGraphAdapter { 4 | const HTTP_URL = process.env.GUN_HTTP_URL || '' 5 | const LMDB_PATH = process.env.GUN_LMDB_PATH || '' 6 | const LMDB_MAP_SIZE = 7 | parseInt(process.env.GUN_LMDB_MAP_SIZE || '', 0) || 1024 ** 3 8 | 9 | if (LMDB_PATH) { 10 | return require('@chaingun/lmdb-adapter').createGraphAdapter({ 11 | mapSize: LMDB_MAP_SIZE, 12 | path: LMDB_PATH 13 | }) 14 | } else if (HTTP_URL) { 15 | return require('@chaingun/http-adapter').createGraphAdapter(HTTP_URL) 16 | } 17 | 18 | // tslint:disable-next-line: no-console 19 | console.warn('Falling back on in-memory storage NO PERSISTENCE') 20 | return require('@chaingun/memory-adapter').createMemoryAdapter() 21 | } 22 | -------------------------------------------------------------------------------- /packages/node-adapters/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "outDir": "build/main", 5 | "rootDir": "src", 6 | "moduleResolution": "node", 7 | "module": "commonjs", 8 | "declaration": true, 9 | "inlineSourceMap": true, 10 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, 11 | 12 | "strict": true /* Enable all strict type-checking options. */, 13 | 14 | /* Strict Type-Checking Options */ 15 | // "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, 16 | // "strictNullChecks": true /* Enable strict null checks. */, 17 | // "strictFunctionTypes": true /* Enable strict checking of function types. */, 18 | // "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */, 19 | // "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, 20 | // "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, 21 | 22 | /* Additional Checks */ 23 | "noUnusedLocals": true /* Report errors on unused locals. */, 24 | "noUnusedParameters": true /* Report errors on unused parameters. */, 25 | "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, 26 | "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, 27 | 28 | /* Debugging Options */ 29 | "traceResolution": false /* Report module resolution log messages. */, 30 | "listEmittedFiles": false /* Print names of generated files part of the compilation. */, 31 | "listFiles": false /* Print names of files part of the compilation. */, 32 | "pretty": true /* Stylize errors and messages using color and context. */, 33 | 34 | /* Experimental Options */ 35 | // "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, 36 | // "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, 37 | 38 | "lib": ["es2017"], 39 | "types": ["node"], 40 | "typeRoots": ["node_modules/@types", "src/types"] 41 | }, 42 | "include": ["src/**/*.ts"], 43 | "exclude": ["node_modules/**"], 44 | "compileOnSave": false 45 | } 46 | -------------------------------------------------------------------------------- /packages/node-adapters/tsconfig.module.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "outDir": "build/module", 6 | "module": "esnext" 7 | }, 8 | "exclude": [ 9 | "node_modules/**" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/node-adapters/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["tslint:latest", "tslint-config-prettier", "tslint-immutable"], 3 | "rules": { 4 | "interface-name": [true, "never-prefix"], 5 | "no-implicit-dependencies": [true, "dev"], 6 | 7 | "no-var-keyword": true, 8 | "no-parameter-reassignment": true, 9 | "typedef": [true, "call-signature"], 10 | 11 | "readonly-keyword": true, 12 | "readonly-array": true, 13 | "no-let": true, 14 | "no-object-mutation": true, 15 | "no-delete": true, 16 | "no-method-signature": true, 17 | 18 | "no-this": true, 19 | "no-class": true, 20 | "no-mixed-interface": true, 21 | "no-expression-statement": [ 22 | true, 23 | { "ignore-prefix": ["console.", "process.exit"] } 24 | ] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/scope/.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # https://circleci.com/docs/2.0/language-javascript/ 2 | version: 2 3 | jobs: 4 | 'node-10': 5 | docker: 6 | - image: circleci/node:10 7 | working_directory: ~/typescript-starter 8 | steps: 9 | - checkout 10 | # Download and cache dependencies 11 | - restore_cache: 12 | keys: 13 | - v1-dependencies-{{ checksum "package.json" }} 14 | # fallback to using the latest cache if no exact match is found 15 | - v1-dependencies- 16 | - run: npm install 17 | - save_cache: 18 | paths: 19 | - node_modules 20 | key: v1-dependencies-{{ checksum "package.json" }} 21 | - run: npm test 22 | - run: npm run cov:send 23 | - run: npm run cov:check 24 | 'node-latest': 25 | docker: 26 | - image: circleci/node:latest 27 | working_directory: ~/typescript-starter 28 | steps: 29 | - checkout 30 | - restore_cache: 31 | keys: 32 | - v1-dependencies-{{ checksum "package.json" }} 33 | - v1-dependencies- 34 | - run: npm install 35 | - save_cache: 36 | paths: 37 | - node_modules 38 | key: v1-dependencies-{{ checksum "package.json" }} 39 | - run: npm test 40 | - run: npm run cov:send 41 | - run: npm run cov:check 42 | 43 | workflows: 44 | version: 2 45 | build: 46 | jobs: 47 | - 'node-10' 48 | - 'node-latest' 49 | -------------------------------------------------------------------------------- /packages/scope/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | max_line_length = 80 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | max_line_length = 0 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /packages/scope/.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Example Contributing Guidelines 2 | 3 | This is an example of GitHub's contributing guidelines file. Check out GitHub's [CONTRIBUTING.md help center article](https://help.github.com/articles/setting-guidelines-for-repository-contributors/) for more information. 4 | -------------------------------------------------------------------------------- /packages/scope/.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **I'm submitting a ...** 2 | [ ] bug report 3 | [ ] feature request 4 | [ ] question about the decisions made in the repository 5 | [ ] question about how to use this project 6 | 7 | * **Summary** 8 | 9 | 10 | 11 | * **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.) 12 | -------------------------------------------------------------------------------- /packages/scope/.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...) 2 | 3 | 4 | 5 | * **What is the current behavior?** (You can also link to an open issue here) 6 | 7 | 8 | 9 | * **What is the new behavior (if this is a feature change)?** 10 | 11 | 12 | 13 | * **Other information**: 14 | -------------------------------------------------------------------------------- /packages/scope/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | test 4 | src/**.js 5 | .idea/* 6 | 7 | coverage 8 | .nyc_output 9 | *.log 10 | 11 | yarn.lock -------------------------------------------------------------------------------- /packages/scope/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | tsconfig.json 4 | tsconfig.module.json 5 | tslint.json 6 | .travis.yml 7 | .github 8 | .prettierignore 9 | .vscode 10 | build/docs 11 | **/*.spec.* 12 | coverage 13 | .nyc_output 14 | *.log 15 | -------------------------------------------------------------------------------- /packages/scope/.prettierignore: -------------------------------------------------------------------------------- 1 | # package.json is formatted by package managers, so we ignore it here 2 | package.json -------------------------------------------------------------------------------- /packages/scope/.vscode/debug-ts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const meow = require('meow'); 3 | const path = require('path'); 4 | 5 | const tsFile = getTSFile(); 6 | const jsFile = TS2JS(tsFile); 7 | 8 | replaceCLIArg(tsFile, jsFile); 9 | 10 | // Ava debugger 11 | require('ava/profile'); 12 | 13 | /** 14 | * get ts file path from CLI args 15 | * 16 | * @return string path 17 | */ 18 | function getTSFile() { 19 | const cli = meow(); 20 | return cli.input[0]; 21 | } 22 | 23 | /** 24 | * get associated compiled js file path 25 | * 26 | * @param tsFile path 27 | * @return string path 28 | */ 29 | function TS2JS(tsFile) { 30 | const srcFolder = path.join(__dirname, '..', 'src'); 31 | const distFolder = path.join(__dirname, '..', 'build', 'main'); 32 | 33 | const tsPathObj = path.parse(tsFile); 34 | 35 | return path.format({ 36 | dir: tsPathObj.dir.replace(srcFolder, distFolder), 37 | ext: '.js', 38 | name: tsPathObj.name, 39 | root: tsPathObj.root 40 | }); 41 | } 42 | 43 | /** 44 | * replace a value in CLI args 45 | * 46 | * @param search value to search 47 | * @param replace value to replace 48 | * @return void 49 | */ 50 | function replaceCLIArg(search, replace) { 51 | process.argv[process.argv.indexOf(search)] = replace; 52 | } -------------------------------------------------------------------------------- /packages/scope/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [{ 4 | "type": "node", 5 | "request": "launch", 6 | "name": "Debug Project", 7 | // we test in `build` to make cleanup fast and easy 8 | "cwd": "${workspaceFolder}/build", 9 | // Replace this with your project root. If there are multiple, you can 10 | // automatically run the currently visible file with: "program": ${file}" 11 | "program": "${workspaceFolder}/src/cli/cli.ts", 12 | // "args": ["--no-install"], 13 | "outFiles": ["${workspaceFolder}/build/main/**/*.js"], 14 | "skipFiles": [ 15 | "/**/*.js", 16 | "${workspaceFolder}/node_modules/**/*.js" 17 | ], 18 | "preLaunchTask": "npm: build", 19 | "stopOnEntry": true, 20 | "smartStep": true, 21 | "runtimeArgs": ["--nolazy"], 22 | "env": { 23 | "TYPESCRIPT_STARTER_REPO_URL": "${workspaceFolder}" 24 | }, 25 | "console": "externalTerminal" 26 | }, 27 | { 28 | "type": "node", 29 | "request": "launch", 30 | "name": "Debug Spec", 31 | "program": "${workspaceRoot}/.vscode/debug-ts.js", 32 | "args": ["${file}"], 33 | "skipFiles": ["/**/*.js"], 34 | // Consider using `npm run watch` or `yarn watch` for faster debugging 35 | // "preLaunchTask": "npm: build", 36 | // "smartStep": true, 37 | "runtimeArgs": ["--nolazy"] 38 | }] 39 | } -------------------------------------------------------------------------------- /packages/scope/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib" 3 | // "typescript.implementationsCodeLens.enabled": true 4 | // "typescript.referencesCodeLens.enabled": true 5 | } 6 | -------------------------------------------------------------------------------- /packages/scope/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 go1dfish 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/scope/README.md: -------------------------------------------------------------------------------- 1 | # @chaingun/scope 2 | 3 | Cached query tools for gunDB useful for SSR 4 | -------------------------------------------------------------------------------- /packages/scope/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './scope'; 2 | -------------------------------------------------------------------------------- /packages/scope/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "outDir": "build/main", 5 | "rootDir": "src", 6 | "moduleResolution": "node", 7 | "module": "commonjs", 8 | "declaration": true, 9 | "inlineSourceMap": true, 10 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, 11 | 12 | // "strict": true /* Enable all strict type-checking options. */, 13 | 14 | /* Strict Type-Checking Options */ 15 | // "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, 16 | // "strictNullChecks": true /* Enable strict null checks. */, 17 | // "strictFunctionTypes": true /* Enable strict checking of function types. */, 18 | // "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */, 19 | // "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, 20 | // "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, 21 | 22 | /* Additional Checks */ 23 | "skipLibCheck": true, 24 | "noUnusedLocals": true /* Report errors on unused locals. */, 25 | "noUnusedParameters": true /* Report errors on unused parameters. */, 26 | "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, 27 | "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, 28 | 29 | /* Debugging Options */ 30 | "traceResolution": false /* Report module resolution log messages. */, 31 | "listEmittedFiles": false /* Print names of generated files part of the compilation. */, 32 | "listFiles": false /* Print names of files part of the compilation. */, 33 | "pretty": true /* Stylize errors and messages using color and context. */, 34 | 35 | /* Experimental Options */ 36 | // "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, 37 | // "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, 38 | 39 | "lib": ["es2017"], 40 | "types": ["node"], 41 | "typeRoots": ["node_modules/@types", "src/types"] 42 | }, 43 | "include": ["src/**/*.ts"], 44 | "exclude": ["node_modules/**"], 45 | "compileOnSave": false 46 | } 47 | -------------------------------------------------------------------------------- /packages/scope/tsconfig.module.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "outDir": "build/module", 6 | "module": "esnext" 7 | }, 8 | "exclude": [ 9 | "node_modules/**" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/scope/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["tslint:latest", "tslint-config-prettier", "tslint-immutable"], 3 | "rules": { 4 | "interface-name": [true, "never-prefix"], 5 | // TODO: allow devDependencies only in **/*.spec.ts files: 6 | // waiting on https://github.com/palantir/tslint/pull/3708 7 | "no-implicit-dependencies": [true, "dev"], 8 | 9 | /* tslint-immutable rules */ 10 | // Recommended built-in rules 11 | "no-var-keyword": true, 12 | "no-parameter-reassignment": true, 13 | "typedef": [true, "call-signature"], 14 | 15 | // Immutability rules 16 | "readonly-keyword": true, 17 | "readonly-array": true, 18 | "no-let": true, 19 | "no-object-mutation": true, 20 | "no-delete": true, 21 | "no-method-signature": true, 22 | 23 | // Functional style rules 24 | "no-this": true, 25 | "no-class": true, 26 | "no-mixed-interface": true, 27 | "no-expression-statement": [ 28 | true, 29 | { "ignore-prefix": ["console.", "process.exit"] } 30 | ], 31 | "no-if-statement": true 32 | /* end tslint-immutable rules */ 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/sea-client/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | max_line_length = 80 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | max_line_length = 0 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /packages/sea-client/.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Example Contributing Guidelines 2 | 3 | This is an example of GitHub's contributing guidelines file. Check out GitHub's [CONTRIBUTING.md help center article](https://help.github.com/articles/setting-guidelines-for-repository-contributors/) for more information. 4 | -------------------------------------------------------------------------------- /packages/sea-client/.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **I'm submitting a ...** 2 | [ ] bug report 3 | [ ] feature request 4 | [ ] question about the decisions made in the repository 5 | [ ] question about how to use this project 6 | 7 | * **Summary** 8 | 9 | 10 | 11 | * **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.) 12 | -------------------------------------------------------------------------------- /packages/sea-client/.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...) 2 | 3 | 4 | 5 | * **What is the current behavior?** (You can also link to an open issue here) 6 | 7 | 8 | 9 | * **What is the new behavior (if this is a feature change)?** 10 | 11 | 12 | 13 | * **Other information**: 14 | -------------------------------------------------------------------------------- /packages/sea-client/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | test 4 | src/**.js 5 | .idea/* 6 | 7 | coverage 8 | .nyc_output 9 | *.log 10 | 11 | package-lock.json -------------------------------------------------------------------------------- /packages/sea-client/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | tsconfig.json 4 | tsconfig.module.json 5 | tslint.json 6 | .travis.yml 7 | .github 8 | .prettierignore 9 | .vscode 10 | build/docs 11 | **/*.spec.* 12 | coverage 13 | .nyc_output 14 | *.log 15 | -------------------------------------------------------------------------------- /packages/sea-client/.prettierignore: -------------------------------------------------------------------------------- 1 | # package.json is formatted by package managers, so we ignore it here 2 | package.json -------------------------------------------------------------------------------- /packages/sea-client/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 go1dfish 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/sea-client/README.md: -------------------------------------------------------------------------------- 1 | # @chaingun/sea-client 2 | 3 | SEA support for @chaingun/client 4 | -------------------------------------------------------------------------------- /packages/sea-client/src/ChainGunSeaClient.ts: -------------------------------------------------------------------------------- 1 | import { ChainGunClient, ChainGunLink } from '@chaingun/client' 2 | import { unpackGraph } from '@chaingun/sear' 3 | import { ChainGunUserApi } from './ChainGunUserApi' 4 | 5 | export class ChainGunSeaClient extends ChainGunClient { 6 | protected readonly _user?: ChainGunUserApi 7 | 8 | constructor(graph: any, LinkClass = ChainGunLink) { 9 | super(graph, LinkClass) 10 | this.registerSearMiddleware() 11 | } 12 | 13 | public user(): ChainGunUserApi { 14 | // @ts-ignore 15 | // tslint:disable-next-line: no-object-mutation 16 | return (this._user = this._user || new ChainGunUserApi(this)) 17 | } 18 | 19 | protected registerSearMiddleware(): void { 20 | this.graph.use(graph => 21 | unpackGraph( 22 | graph, 23 | // tslint:disable-next-line: no-string-literal 24 | this.graph['_opt'].mutable ? 'mutable' : 'immutable' 25 | ) 26 | ) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/sea-client/src/ChainGunUserApi.ts: -------------------------------------------------------------------------------- 1 | import { authenticate, createUser, graphSigner } from '@chaingun/sear' 2 | import { ChainGunSeaClient } from './ChainGunSeaClient' 3 | 4 | interface UserReference { 5 | readonly alias: string 6 | readonly pub: string 7 | } 8 | 9 | interface AckErr { 10 | readonly err: Error 11 | } 12 | 13 | interface UserCredentials { 14 | readonly priv: string 15 | readonly epriv: any 16 | readonly alias: string 17 | readonly pub: string 18 | readonly epub: string 19 | } 20 | 21 | type LoginCallback = (userRef: UserReference | AckErr) => void 22 | 23 | const DEFAULT_CREATE_OPTS = {} 24 | const DEFAULT_AUTH_OPTS = {} 25 | 26 | export class ChainGunUserApi { 27 | public readonly is?: UserReference 28 | private readonly _gun: ChainGunSeaClient 29 | private readonly _signMiddleware?: (graph: any) => Promise 30 | 31 | constructor(gun: ChainGunSeaClient) { 32 | this._gun = gun 33 | } 34 | 35 | /** 36 | * 37 | * https://gun.eco/docs/User#user-create 38 | * 39 | * @param alias 40 | * @param password 41 | * @param cb 42 | * @param opt 43 | */ 44 | public async create( 45 | alias: string, 46 | password: string, 47 | cb?: LoginCallback, 48 | _opt = DEFAULT_CREATE_OPTS 49 | ): Promise<{ 50 | readonly alias: string 51 | readonly pub: string 52 | }> { 53 | try { 54 | const user = await createUser(this._gun, alias, password) 55 | const ref = this.useCredentials(user) 56 | if (cb) { 57 | cb(ref) 58 | } 59 | return ref 60 | } catch (err) { 61 | if (cb) { 62 | cb({ err }) 63 | } 64 | throw err 65 | } 66 | } 67 | 68 | /** 69 | * 70 | * https://gun.eco/docs/User#user-auth 71 | * 72 | * @param alias 73 | * @param password 74 | * @param cb 75 | * @param opt 76 | */ 77 | public async auth( 78 | alias: string, 79 | password: string, 80 | cb?: LoginCallback, 81 | _opt = DEFAULT_AUTH_OPTS 82 | ): Promise<{ 83 | readonly alias: string 84 | readonly pub: string 85 | }> { 86 | try { 87 | const user = await authenticate(this._gun, alias, password) 88 | const ref = this.useCredentials(user) 89 | if (cb) { 90 | cb(ref) 91 | } 92 | return ref 93 | } catch (err) { 94 | if (cb) { 95 | cb({ err }) 96 | } 97 | throw err 98 | } 99 | } 100 | 101 | /** 102 | * https://gun.eco/docs/User#user-leave 103 | */ 104 | public leave(): ChainGunUserApi { 105 | if (this._signMiddleware) { 106 | this._gun.graph.unuse(this._signMiddleware, 'write') 107 | // @ts-ignore 108 | // tslint:disable-next-line: no-object-mutation 109 | this._signMiddleware = undefined 110 | // @ts-ignore 111 | // tslint:disable-next-line: no-object-mutation 112 | this.is = undefined 113 | } 114 | 115 | return this 116 | } 117 | 118 | public useCredentials( 119 | credentials: UserCredentials 120 | ): { 121 | readonly alias: string 122 | readonly pub: string 123 | } { 124 | this.leave() 125 | // @ts-ignore 126 | // tslint:disable-next-line: no-object-mutation 127 | this._signMiddleware = graphSigner({ 128 | priv: credentials.priv, 129 | pub: credentials.pub 130 | }) 131 | this._gun.graph.use(this._signMiddleware, 'write') 132 | // @ts-ignore 133 | // tslint:disable-next-line: no-object-mutation 134 | return (this.is = { 135 | alias: credentials.alias, 136 | pub: credentials.pub 137 | }) 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /packages/sea-client/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@chaingun/client' 2 | export * from '@chaingun/sear' 3 | export { ChainGunSeaClient } from './ChainGunSeaClient' 4 | export { ChainGunUserApi } from './ChainGunUserApi' 5 | -------------------------------------------------------------------------------- /packages/sea-client/src/interfaces.ts: -------------------------------------------------------------------------------- 1 | interface GunNodeState { 2 | [key: string]: number 3 | } 4 | 5 | interface GunNode { 6 | _: { 7 | '#': string 8 | '>': GunNodeState 9 | } 10 | [key: string]: any 11 | } 12 | 13 | interface GunGraphData { 14 | [key: string]: GunNode | undefined 15 | } 16 | 17 | interface GunMsg { 18 | '#'?: string 19 | '@'?: string 20 | 21 | get?: { 22 | '#': string 23 | } 24 | 25 | put?: { 26 | [soul: string]: GunNode 27 | } 28 | } 29 | 30 | type GunValue = object | string | number | boolean | null 31 | type ChainGunOptions = any 32 | type GunChainOptions = any 33 | type SendFn = (msg: GunMsg) => void 34 | type GunOnCb = (node: GunValue | undefined, key?: string) => void 35 | type GunPutCb = (res: { ack: number; err?: any }) => void 36 | type GunNodeListenCb = (node: GunNode | undefined) => void 37 | 38 | interface PathData { 39 | souls: string[] 40 | value: GunValue | undefined 41 | complete: boolean 42 | } 43 | 44 | type ChainGunMiddleware = ( 45 | updates: GunGraphData, 46 | existingGraph: GunGraphData 47 | ) => GunGraphData | undefined | Promise 48 | type ChainGunMiddlewareType = 'read' | 'write' 49 | -------------------------------------------------------------------------------- /packages/sea-client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "outDir": "build/main", 5 | "rootDir": "src", 6 | "moduleResolution": "node", 7 | "module": "commonjs", 8 | "declaration": true, 9 | "inlineSourceMap": true, 10 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, 11 | 12 | "strict": true /* Enable all strict type-checking options. */, 13 | 14 | /* Strict Type-Checking Options */ 15 | // "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, 16 | // "strictNullChecks": true /* Enable strict null checks. */, 17 | // "strictFunctionTypes": true /* Enable strict checking of function types. */, 18 | // "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */, 19 | // "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, 20 | // "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, 21 | 22 | /* Additional Checks */ 23 | "noUnusedLocals": true /* Report errors on unused locals. */, 24 | "noUnusedParameters": true /* Report errors on unused parameters. */, 25 | "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, 26 | "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, 27 | 28 | /* Debugging Options */ 29 | "traceResolution": false /* Report module resolution log messages. */, 30 | "listEmittedFiles": false /* Print names of generated files part of the compilation. */, 31 | "listFiles": false /* Print names of files part of the compilation. */, 32 | "pretty": true /* Stylize errors and messages using color and context. */, 33 | 34 | /* Experimental Options */ 35 | // "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, 36 | // "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, 37 | 38 | "lib": ["es2017", "dom"], 39 | "types": [], 40 | "typeRoots": ["node_modules/@types", "src/types"] 41 | }, 42 | "include": ["src/**/*.ts"], 43 | "exclude": ["node_modules/**"], 44 | "compileOnSave": false 45 | } 46 | -------------------------------------------------------------------------------- /packages/sea-client/tsconfig.module.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "outDir": "build/module", 6 | "module": "esnext" 7 | }, 8 | "exclude": [ 9 | "node_modules/**" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/sea-client/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["tslint:latest", "tslint-config-prettier", "tslint-immutable"], 3 | "rules": { 4 | "variable-name": false, 5 | "interface-name": [true, "never-prefix"], 6 | "no-implicit-dependencies": [true, "dev"], 7 | 8 | "no-var-keyword": true, 9 | "no-parameter-reassignment": true, 10 | "typedef": [true, "call-signature"], 11 | 12 | "readonly-keyword": true, 13 | "readonly-array": true, 14 | "no-let": true, 15 | "no-object-mutation": true, 16 | "no-delete": true, 17 | "no-method-signature": true, 18 | 19 | "no-mixed-interface": true 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/sear/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | max_line_length = 80 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | max_line_length = 0 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /packages/sear/.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Example Contributing Guidelines 2 | 3 | This is an example of GitHub's contributing guidelines file. Check out GitHub's [CONTRIBUTING.md help center article](https://help.github.com/articles/setting-guidelines-for-repository-contributors/) for more information. 4 | -------------------------------------------------------------------------------- /packages/sear/.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **I'm submitting a ...** 2 | [ ] bug report 3 | [ ] feature request 4 | [ ] question about the decisions made in the repository 5 | [ ] question about how to use this project 6 | 7 | * **Summary** 8 | 9 | 10 | 11 | * **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.) 12 | -------------------------------------------------------------------------------- /packages/sear/.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...) 2 | 3 | 4 | 5 | * **What is the current behavior?** (You can also link to an open issue here) 6 | 7 | 8 | 9 | * **What is the new behavior (if this is a feature change)?** 10 | 11 | 12 | 13 | * **Other information**: 14 | -------------------------------------------------------------------------------- /packages/sear/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | test 4 | src/**.js 5 | .idea/* 6 | 7 | coverage 8 | .nyc_output 9 | *.log 10 | 11 | package-lock.json -------------------------------------------------------------------------------- /packages/sear/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | tsconfig.json 4 | tsconfig.module.json 5 | tslint.json 6 | .travis.yml 7 | .github 8 | .prettierignore 9 | .vscode 10 | build/docs 11 | **/*.spec.* 12 | coverage 13 | .nyc_output 14 | *.log 15 | -------------------------------------------------------------------------------- /packages/sear/.prettierignore: -------------------------------------------------------------------------------- 1 | # package.json is formatted by package managers, so we ignore it here 2 | package.json -------------------------------------------------------------------------------- /packages/sear/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 go1dfish 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/sear/README.md: -------------------------------------------------------------------------------- 1 | # @chaingun/sear 2 | 3 | A refactor of Gun's SEA logic in TypeScript, not dependent on gun.js 4 | -------------------------------------------------------------------------------- /packages/sear/src/SafeBuffer.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable 2 | 3 | // This is Buffer implementation used in SEA. Functionality is mostly 4 | // compatible with NodeJS 'safe-buffer' and is used for encoding conversions 5 | // between binary and 'hex' | 'utf8' | 'base64' 6 | // See documentation and validation for safe implementation in: 7 | // https://github.com/feross/safe-buffer#update 8 | import SeaArray from './SeaArray' 9 | import { base64 } from './base64' 10 | 11 | function SafeBuffer(...props: any[]) { 12 | console.warn('new SafeBuffer() is depreciated, please use SafeBuffer.from()') 13 | return (SafeBuffer).from(...props) 14 | } 15 | SafeBuffer.prototype = Object.create(Array.prototype) 16 | Object.assign(SafeBuffer, { 17 | // (data, enc) where typeof data === 'string' then enc === 'utf8'|'hex'|'base64' 18 | from() { 19 | if (!Object.keys(arguments).length) { 20 | throw new TypeError( 21 | 'First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.' 22 | ) 23 | } 24 | const input = arguments[0] 25 | let buf 26 | if (typeof input === 'string') { 27 | const enc = arguments[1] || 'utf8' 28 | if (enc === 'hex') { 29 | const bytes = (input) 30 | .match(/([\da-fA-F]{2})/g) 31 | .map((byte: string) => parseInt(byte, 16)) 32 | if (!bytes || !bytes.length) { 33 | throw new TypeError("Invalid first argument for type 'hex'.") 34 | } 35 | buf = SeaArray.from(bytes) 36 | } else if (enc === 'utf8') { 37 | const length = input.length 38 | const words = new Uint16Array(length) 39 | for (let i = 0; i < length; i++) { 40 | words[i] = input.charCodeAt(i) 41 | } 42 | buf = SeaArray.from(words) 43 | } else if (enc === 'base64') { 44 | const dec = base64.atob(input) 45 | const length = dec.length 46 | const bytes = new Uint8Array(length) 47 | for (let i = 0; i < length; i++) { 48 | bytes[i] = dec.charCodeAt(i) 49 | } 50 | buf = SeaArray.from(bytes) 51 | } else if (enc === 'binary') { 52 | buf = SeaArray.from(input) 53 | } else { 54 | console.info('SafeBuffer.from unknown encoding: ' + enc) 55 | } 56 | return buf 57 | } 58 | const length = input.byteLength ? input.byteLength : input.length 59 | if (length) { 60 | let buf 61 | if (input instanceof ArrayBuffer) { 62 | buf = new Uint8Array(input) 63 | } 64 | return SeaArray.from(buf || input) 65 | } 66 | }, 67 | // This is 'safe-buffer.alloc' sans encoding support 68 | alloc(length: number, fill = 0 /*, enc */) { 69 | return SeaArray.from( 70 | new Uint8Array(Array.from({ length: length }, () => fill)) 71 | ) 72 | }, 73 | // This is normal UNSAFE 'buffer.alloc' or 'new Buffer(length)' - don't use! 74 | allocUnsafe(length: number) { 75 | return SeaArray.from(new Uint8Array(Array.from({ length: length }))) 76 | }, 77 | // This puts together array of array like members 78 | concat(arr: any[]) { 79 | // octet array 80 | if (!Array.isArray(arr)) { 81 | throw new TypeError( 82 | 'First argument must be Array containing ArrayBuffer or Uint8Array instances.' 83 | ) 84 | } 85 | return SeaArray.from( 86 | arr.reduce((ret, item) => ret.concat(Array.from(item)), []) 87 | ) 88 | } 89 | }) 90 | SafeBuffer.prototype.from = (SafeBuffer).from 91 | SafeBuffer.prototype.toString = SeaArray.prototype.toString 92 | 93 | export default SafeBuffer 94 | -------------------------------------------------------------------------------- /packages/sear/src/SeaArray.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable 2 | 3 | import { base64 } from './base64' 4 | 5 | // This is Array extended to have .toString(['utf8'|'hex'|'base64']) 6 | function SeaArray() {} 7 | Object.assign(SeaArray, { from: Array.from }) 8 | SeaArray.prototype = Object.create(Array.prototype) 9 | SeaArray.prototype.toString = function(enc: string, start: number, end: number) { 10 | enc = enc || 'utf8' 11 | start = start || 0 12 | const length = this.length 13 | if (enc === 'hex') { 14 | const buf = new Uint8Array(this) 15 | const num = ((end && end + 1) || length) - start 16 | let res = '' 17 | for (let i = 0; i < num; i++) { 18 | res += buf[i + start].toString(16).padStart(2, '0') 19 | } 20 | return res 21 | } 22 | if (enc === 'utf8') { 23 | const num = (end || length) - start 24 | let res = '' 25 | for (let i = 0; i < num; i++) { 26 | res += String.fromCharCode(this[i + start]) 27 | } 28 | return res 29 | } 30 | if (enc === 'base64') { 31 | return base64.btoa(this) 32 | } 33 | } 34 | 35 | export default SeaArray 36 | -------------------------------------------------------------------------------- /packages/sear/src/authenticate.ts: -------------------------------------------------------------------------------- 1 | import { decrypt } from './decrypt' 2 | import { work } from './work' 3 | 4 | const DEFAULT_OPTS = {} 5 | 6 | export async function authenticateAccount( 7 | ident: any, 8 | password: string, 9 | encoding = 'base64' 10 | ): Promise< 11 | | undefined 12 | | { 13 | readonly alias: string 14 | readonly epriv: string 15 | readonly epub: string 16 | readonly priv: string 17 | readonly pub: string 18 | } 19 | > { 20 | if (!ident || !ident.auth) { 21 | return 22 | } 23 | 24 | // tslint:disable-next-line: no-let 25 | let decrypted: any 26 | try { 27 | const proof = await work(password, ident.auth.s, { encode: encoding }) 28 | decrypted = await decrypt(ident.auth.ek, proof, { 29 | encode: encoding 30 | }) 31 | } catch (err) { 32 | const proof = await work(password, ident.auth.s, { encode: 'utf8' }) 33 | decrypted = await decrypt(ident.auth.ek, proof, { 34 | encode: encoding 35 | }) 36 | } 37 | 38 | if (!decrypted) { 39 | return 40 | } 41 | 42 | return { 43 | alias: ident.alias as string, 44 | epriv: decrypted.epriv as string, 45 | epub: ident.epub as string, 46 | priv: decrypted.priv as string, 47 | pub: ident.pub as string 48 | } 49 | } 50 | 51 | export async function authenticateIdentity( 52 | chaingun: any, 53 | soul: string, 54 | password: string, 55 | encoding = 'base64' 56 | ): Promise< 57 | | undefined 58 | | { 59 | readonly alias: string 60 | readonly epriv: string 61 | readonly epub: string 62 | readonly priv: string 63 | readonly pub: string 64 | } 65 | > { 66 | const ident = await chaingun.get(soul).then() 67 | return authenticateAccount(ident, password, encoding) 68 | } 69 | 70 | export async function authenticate( 71 | chaingun: any, 72 | alias: string, 73 | password: string, 74 | _opt = DEFAULT_OPTS 75 | ): Promise<{ 76 | readonly alias: string 77 | readonly epriv: string 78 | readonly epub: string 79 | readonly priv: string 80 | readonly pub: string 81 | }> { 82 | const aliasSoul = `~@${alias}` 83 | const idents = await chaingun.get(aliasSoul).then() 84 | for (const soul in idents || {}) { 85 | if (soul === '_') { 86 | continue 87 | } 88 | 89 | // tslint:disable-next-line: no-let 90 | let pair 91 | 92 | try { 93 | pair = await authenticateIdentity(chaingun, soul, password) 94 | } catch (e) { 95 | // tslint:disable-next-line: no-console 96 | console.warn(e.stack || e) 97 | } 98 | 99 | if (pair) { 100 | return pair 101 | } 102 | } 103 | 104 | throw new Error('Wrong alias or password.') 105 | } 106 | -------------------------------------------------------------------------------- /packages/sear/src/base64.ts: -------------------------------------------------------------------------------- 1 | export const base64: any = {} 2 | 3 | // tslint:disable-next-line strict-type-predicates 4 | if (typeof btoa === 'undefined') { 5 | // tslint:disable-next-line: no-object-mutation 6 | base64.btoa = function btoa(b: any): string { 7 | return Buffer.from(b, 'binary').toString('base64') 8 | } 9 | } else { 10 | // tslint:disable-next-line: no-object-mutation 11 | base64.btoa = (x: string) => btoa(x) 12 | } 13 | 14 | // tslint:disable-next-line strict-type-predicates 15 | if (typeof atob === 'undefined') { 16 | // tslint:disable-next-line: no-object-mutation 17 | base64.atob = function atob(b: any): string { 18 | return Buffer.from(b, 'base64').toString('binary') 19 | } 20 | } else { 21 | // tslint:disable-next-line: no-object-mutation 22 | base64.atob = (x: string) => atob(x) 23 | } 24 | -------------------------------------------------------------------------------- /packages/sear/src/createUser.ts: -------------------------------------------------------------------------------- 1 | import { encrypt } from './encrypt' 2 | import { pair as createPair } from './pair' 3 | import { pseudoRandomText } from './pseudoRandomText' 4 | import { signGraph } from './sign' 5 | import { work } from './work' 6 | 7 | // TODO: refactor to not require chaingun 8 | export async function createUser( 9 | chaingun: any, 10 | alias: string, 11 | password: string 12 | ): Promise<{ 13 | readonly alias: string 14 | readonly auth: string 15 | readonly epub: string 16 | readonly pub: string 17 | readonly epriv: string 18 | readonly priv: string 19 | }> { 20 | const aliasSoul = `~@${alias}` 21 | 22 | // "pseudo-randomly create a salt, then use PBKDF2 function to extend the password with it." 23 | const salt = pseudoRandomText(64) 24 | const proof = await work(password, salt) 25 | const pair = await createPair() 26 | const { pub, priv, epub, epriv } = pair 27 | const pubSoul = `~${pub}` 28 | 29 | // "to keep the private key safe, we AES encrypt it with the proof of work!" 30 | const ek = await encrypt(JSON.stringify({ priv, epriv }), proof, { 31 | raw: true 32 | }) 33 | const auth = JSON.stringify({ ek, s: salt }) 34 | const data = { 35 | alias, 36 | auth, 37 | epub, 38 | pub 39 | } 40 | 41 | const now = new Date().getTime() 42 | 43 | const graph = await signGraph( 44 | { 45 | [pubSoul]: { 46 | _: { 47 | '#': pubSoul, 48 | '>': Object.keys(data).reduce( 49 | // tslint:disable-next-line: readonly-keyword 50 | (state: { [key: string]: number }, key) => { 51 | // tslint:disable-next-line: no-object-mutation 52 | state[key] = now 53 | return state 54 | }, 55 | {} 56 | ) 57 | }, 58 | ...data 59 | } 60 | }, 61 | { pub, priv } 62 | ) 63 | 64 | await new Promise(ok => chaingun.get(aliasSoul).put(graph, ok)) 65 | 66 | return { 67 | ...data, 68 | epriv, 69 | priv, 70 | pub 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /packages/sear/src/decrypt.ts: -------------------------------------------------------------------------------- 1 | import { importAesKey } from './importAesKey' 2 | import { parse } from './settings' 3 | import { Buffer, crypto, TextDecoder } from './shims' 4 | 5 | const DEFAULT_OPTS: { 6 | readonly name?: string 7 | readonly encode?: string 8 | readonly fallback?: string 9 | } = { 10 | encode: 'base64', 11 | name: 'AES-GCM' 12 | } 13 | 14 | export async function decrypt( 15 | data: string, 16 | key: string, 17 | opt = DEFAULT_OPTS 18 | ): Promise { 19 | const json: any = parse(data) 20 | const encoding = opt.encode || DEFAULT_OPTS.encode 21 | 22 | try { 23 | const aeskey = await importAesKey(key, Buffer.from(json.s, encoding), opt) 24 | const encrypted = new Uint8Array(Buffer.from(json.ct, encoding)) 25 | const iv = new Uint8Array(Buffer.from(json.iv, encoding)) 26 | const ct = await crypto.subtle.decrypt( 27 | { 28 | iv, 29 | name: opt.name || DEFAULT_OPTS.name || 'AES-GCM', 30 | tagLength: 128 31 | }, 32 | aeskey, 33 | encrypted 34 | ) 35 | return parse(new TextDecoder('utf8').decode(ct)) 36 | } catch (e) { 37 | // tslint:disable-next-line: no-console 38 | console.warn('decrypt error', e, e.stack || e) 39 | 40 | if (!opt.fallback || encoding === opt.fallback) { 41 | throw new Error('Could not decrypt') 42 | } 43 | return decrypt(data, key, { ...opt, encode: opt.fallback }) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/sear/src/encrypt.ts: -------------------------------------------------------------------------------- 1 | import { importAesKey } from './importAesKey' 2 | import { Buffer, crypto, random, TextEncoder } from './shims' 3 | 4 | const DEFAULT_OPTS: { 5 | readonly name?: string 6 | readonly encode?: string 7 | readonly raw?: boolean 8 | } = { 9 | encode: 'base64', 10 | name: 'AES-GCM' 11 | } 12 | 13 | export async function encrypt( 14 | msg: string, 15 | key: string, 16 | opt = DEFAULT_OPTS 17 | ): Promise< 18 | | string 19 | | { 20 | readonly ct: string 21 | readonly iv: string 22 | readonly s: string 23 | } 24 | > { 25 | const rand = { s: random(9), iv: random(15) } // consider making this 9 and 15 or 18 or 12 to reduce == padding. 26 | 27 | const ct = await crypto.subtle.encrypt( 28 | { 29 | iv: new Uint8Array(rand.iv), 30 | name: opt.name || DEFAULT_OPTS.name || 'AES-GCM' 31 | }, 32 | await importAesKey(key, rand.s, opt), 33 | new TextEncoder().encode(msg) 34 | ) 35 | const encoding = opt.encode || DEFAULT_OPTS.encode 36 | const r = { 37 | ct: Buffer.from(ct, 'binary').toString(encoding), 38 | iv: rand.iv.toString(encoding), 39 | s: rand.s.toString(encoding) 40 | } 41 | if (opt.raw) { 42 | return r 43 | } 44 | return 'SEA' + JSON.stringify(r) 45 | } 46 | -------------------------------------------------------------------------------- /packages/sear/src/importAesKey.ts: -------------------------------------------------------------------------------- 1 | import { keyToJwk } from './settings' 2 | import { sha256 } from './sha256' 3 | import { crypto, random } from './shims' 4 | 5 | const DEFAULT_OPTS: { 6 | readonly name?: string 7 | } = { 8 | name: 'AES-GCM' 9 | } 10 | 11 | export async function importAesKey( 12 | key: string, 13 | salt: Buffer, 14 | _opt = DEFAULT_OPTS 15 | ): Promise { 16 | const combo = key + (salt || random(8)).toString('utf8') 17 | const hash = await sha256(combo) 18 | const jwkKey = keyToJwk(hash) 19 | return crypto.subtle.importKey('jwk', jwkKey, 'AES-GCM', false, [ 20 | 'encrypt', 21 | 'decrypt' 22 | ]) 23 | } 24 | -------------------------------------------------------------------------------- /packages/sear/src/index.ts: -------------------------------------------------------------------------------- 1 | import * as _shims from './shims' 2 | 3 | export * from './settings' 4 | export * from './unpack' 5 | export { authenticate, authenticateAccount } from './authenticate' 6 | export { createUser } from './createUser' 7 | export { decrypt } from './decrypt' 8 | export { encrypt } from './encrypt' 9 | export { importAesKey } from './importAesKey' 10 | export { pair } from './pair' 11 | export { pseudoRandomText } from './pseudoRandomText' 12 | export { sha256 } from './sha256' 13 | export { work } from './work' 14 | export * from './sign' 15 | export { pubFromSoul } from './soul' 16 | export { verify, verifySignature, verifyHashSignature } from './verify' 17 | 18 | export const shims = _shims 19 | -------------------------------------------------------------------------------- /packages/sear/src/interfaces.ts: -------------------------------------------------------------------------------- 1 | interface GunNodeState { 2 | readonly [key: string]: number 3 | } 4 | 5 | interface GunNodeMeta { 6 | readonly '#': string 7 | readonly '>': GunNodeState 8 | } 9 | 10 | interface GunNode { 11 | readonly _: GunNodeMeta 12 | // tslint:disable-next-line: no-mixed-interface 13 | readonly [key: string]: GunValue 14 | } 15 | 16 | interface GunGraphData { 17 | readonly [key: string]: GunNode | undefined 18 | } 19 | 20 | interface GunMsg { 21 | readonly '#'?: string 22 | readonly '##'?: string | number 23 | 24 | readonly get?: { 25 | readonly '#': string 26 | } 27 | 28 | readonly put?: { 29 | readonly [soul: string]: GunNode 30 | } 31 | } 32 | 33 | type GunValue = object | string | number | boolean | null 34 | -------------------------------------------------------------------------------- /packages/sear/src/pair.ts: -------------------------------------------------------------------------------- 1 | import { ecdh, ecdsa } from './settings' 2 | import { crypto } from './shims' 3 | 4 | export async function pair(_opt?: any): Promise<{ 5 | readonly epriv: string 6 | readonly epub: string 7 | readonly priv: string 8 | readonly pub: string 9 | }> { 10 | const signKeys = await crypto.subtle.generateKey(ecdsa.pair, true, [ 11 | 'sign', 12 | 'verify' 13 | ]) 14 | const signPub = await crypto.subtle.exportKey('jwk', signKeys.publicKey) 15 | const sa = { 16 | priv: (await crypto.subtle.exportKey('jwk', signKeys.privateKey)).d, 17 | pub: `${signPub.x}.${signPub.y}` 18 | } 19 | 20 | const cryptKeys = await crypto.subtle.generateKey(ecdh, true, ['deriveKey']) 21 | const cryptPub = await crypto.subtle.exportKey('jwk', cryptKeys.publicKey) 22 | const dh = { 23 | epriv: (await crypto.subtle.exportKey('jwk', cryptKeys.privateKey)).d, 24 | epub: `${cryptPub.x}.${cryptPub.y}` 25 | } 26 | 27 | return { 28 | epriv: dh.epriv || '', 29 | epub: dh.epub, 30 | priv: sa.priv || '', 31 | pub: sa.pub 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/sear/src/pseudoRandomText.ts: -------------------------------------------------------------------------------- 1 | export function pseudoRandomText( 2 | l = 24, 3 | c = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXZabcdefghijklmnopqrstuvwxyz' 4 | ): string { 5 | // tslint:disable-next-line: no-let 6 | let s = '' 7 | while (l > 0) { 8 | s += c.charAt(Math.floor(Math.random() * c.length)) 9 | // tslint:disable-next-line: no-parameter-reassignment 10 | l-- 11 | } 12 | return s 13 | } 14 | -------------------------------------------------------------------------------- /packages/sear/src/settings.ts: -------------------------------------------------------------------------------- 1 | export const shuffleAttackCutoff = 1546329600000 // Jan 1, 2019 2 | 3 | export const pbkdf2 = { hash: { name: 'SHA-256' }, iter: 100000, ks: 64 } 4 | export const ecdsa = { 5 | pair: { name: 'ECDSA', namedCurve: 'P-256' }, 6 | sign: { name: 'ECDSA', hash: { name: 'SHA-256' } } 7 | } 8 | export const ecdh = { name: 'ECDH', namedCurve: 'P-256' } 9 | 10 | // This creates Web Cryptography API compliant JWK for sign/verify purposes 11 | export function jwk( 12 | pub: string, 13 | d?: string 14 | ): { 15 | readonly crv: string 16 | readonly d?: string 17 | readonly ext: boolean 18 | readonly key_opts: readonly string[] 19 | readonly kty: string 20 | readonly x: string 21 | readonly y: string 22 | } { 23 | // d === priv 24 | const coords = pub.split('.') 25 | return { 26 | crv: 'P-256', 27 | d, 28 | ext: true, 29 | key_opts: d ? ['sign'] : ['verify'], 30 | kty: 'EC', 31 | x: coords[0], 32 | y: coords[1] 33 | } 34 | } 35 | 36 | export function keyToJwk( 37 | keyBytes: Buffer 38 | ): { 39 | readonly k: string 40 | readonly kty: string 41 | readonly ext: boolean 42 | readonly alg: string 43 | } { 44 | const keyB64 = keyBytes.toString('base64') 45 | const k = keyB64 46 | .replace(/\+/g, '-') 47 | .replace(/\//g, '_') 48 | .replace(/\=/g, '') 49 | return { kty: 'oct', k, ext: false, alg: 'A256GCM' } 50 | } 51 | 52 | export function check(t: any): boolean { 53 | return typeof t === 'string' && 'SEA{' === t.slice(0, 4) 54 | } 55 | 56 | export function parse(t: any): any { 57 | try { 58 | const yes = typeof t === 'string' 59 | if (yes && 'SEA{' === t.slice(0, 4)) { 60 | // tslint:disable-next-line: no-parameter-reassignment 61 | t = t.slice(3) 62 | } 63 | return yes ? JSON.parse(t) : t 64 | // tslint:disable-next-line: no-empty 65 | } catch (_e) {} 66 | return t 67 | } 68 | -------------------------------------------------------------------------------- /packages/sear/src/sha256.ts: -------------------------------------------------------------------------------- 1 | import { Buffer, crypto, TextEncoder } from './shims' 2 | 3 | export async function sha256(input: string, name = 'SHA-256'): Promise { 4 | const inp = typeof input === 'string' ? input : JSON.stringify(input) 5 | const encoded = new TextEncoder().encode(inp) 6 | const hash = await crypto.subtle.digest({ name }, encoded) 7 | return Buffer.from(hash) 8 | } 9 | -------------------------------------------------------------------------------- /packages/sear/src/shims.ts: -------------------------------------------------------------------------------- 1 | import root from 'window-or-global'; 2 | import './base64'; 3 | import SafeBuffer from './SafeBuffer'; 4 | 5 | // tslint:disable-next-line: no-var-requires 6 | const isocrypto = require('isomorphic-webcrypto'); 7 | 8 | export const crypto = isocrypto.default || isocrypto; 9 | 10 | export const Buffer = SafeBuffer; 11 | 12 | const api: any = { 13 | Buffer, 14 | TextDecoder: root && root.TextDecoder, 15 | TextEncoder: root && root.TextEncoder 16 | }; 17 | // tslint:disable-next-line: no-expression-statement no-object-mutation 18 | api.random = (len: number) => 19 | api.Buffer.from( 20 | crypto.getRandomValues(new Uint8Array(api.Buffer.alloc(len))) 21 | ); 22 | 23 | if (!api.TextEncoder) { 24 | // tslint:disable-next-line: no-eval no-shadowed-variable 25 | const { TextEncoder, TextDecoder } = eval('require')('text-encoding'); 26 | // tslint:disable-next-line: no-expression-statement no-object-mutation 27 | api.TextEncoder = TextEncoder; 28 | // tslint:disable-next-line: no-expression-statement no-object-mutation 29 | api.TextDecoder = TextDecoder; 30 | } 31 | 32 | export const TextEncoder = api.TextEncoder; 33 | export const TextDecoder = api.TextDecoder; 34 | export const random = api.random; 35 | -------------------------------------------------------------------------------- /packages/sear/src/soul.ts: -------------------------------------------------------------------------------- 1 | export function pubFromSoul(soul: string): string { 2 | if (!soul) { 3 | return '' 4 | } 5 | const tokens = soul.split('~') 6 | const last = tokens[tokens.length - 1] 7 | if (!last) { 8 | return '' 9 | } 10 | const coords = last.split('.') 11 | if (coords.length < 2) { 12 | return '' 13 | } 14 | return coords.slice(0, 2).join('.') 15 | } 16 | -------------------------------------------------------------------------------- /packages/sear/src/unpack.ts: -------------------------------------------------------------------------------- 1 | import { check, parse, shuffleAttackCutoff } from './settings' 2 | import { pubFromSoul } from './soul' 3 | 4 | export function unpack(passedValue: any, key: string, node: GunNode): any { 5 | // tslint:disable-next-line: no-let 6 | let value = passedValue 7 | 8 | if (!value) { 9 | return 10 | } 11 | 12 | if (typeof value === 'object' && ':' in value) { 13 | const val = value[':'] 14 | if (typeof val !== 'undefined') { 15 | return val 16 | } 17 | } 18 | 19 | if (typeof value === 'object' && 'm' in value) { 20 | const val = value.m 21 | if (typeof val !== 'undefined') { 22 | value = parse(val) 23 | } 24 | } 25 | 26 | if (!key || !node) { 27 | return 28 | } 29 | if (value === node[key]) { 30 | return value 31 | } 32 | if (!check(node[key])) { 33 | return value 34 | } 35 | const soul = node && node._ && node._['#'] 36 | const state = node && node._ && node._['>'] && node._['>'][key] 37 | if ( 38 | value && 39 | 4 === value.length && 40 | soul === value[0] && 41 | key === value[1] && 42 | Math.floor(state) === Math.floor(value[3]) 43 | ) { 44 | return value[2] 45 | } 46 | if (state < shuffleAttackCutoff) { 47 | return value 48 | } 49 | } 50 | 51 | export function unpackNode( 52 | node: GunNode, 53 | mut: 'immutable' | 'mutable' = 'immutable' 54 | ): GunNode { 55 | if (!node) { 56 | return node 57 | } 58 | 59 | const result: GunNode = 60 | mut === 'mutable' 61 | ? node 62 | : { 63 | _: node._ 64 | } 65 | 66 | for (const key in node) { 67 | if (key === '_') { 68 | continue 69 | } 70 | // @ts-ignore 71 | // tslint:disable-next-line: no-object-mutation 72 | result[key] = unpack(parse(node[key]), key, node) 73 | } 74 | 75 | return result 76 | } 77 | 78 | export function unpackGraph( 79 | graph: GunGraphData, 80 | mut: 'immutable' | 'mutable' = 'immutable' 81 | ): GunGraphData { 82 | const unpackedGraph: GunGraphData = mut === 'mutable' ? graph : {} 83 | 84 | for (const soul in graph) { 85 | if (!soul) { 86 | continue 87 | } 88 | 89 | const node = graph[soul] 90 | const pub = pubFromSoul(soul) 91 | 92 | // @ts-ignore 93 | // tslint:disable-next-line: no-object-mutation 94 | unpackedGraph[soul] = node && pub ? unpackNode(node, mut) : node 95 | } 96 | 97 | return unpackedGraph 98 | } 99 | -------------------------------------------------------------------------------- /packages/sear/src/verify.ts: -------------------------------------------------------------------------------- 1 | import { ecdsa, jwk, parse } from './settings' 2 | import { sha256 } from './sha256' 3 | import { crypto } from './shims' 4 | 5 | const DEFAULT_OPTS: { 6 | readonly fallback?: boolean 7 | readonly encode?: string 8 | readonly raw?: boolean 9 | readonly check?: { 10 | readonly m: any 11 | readonly s: string 12 | } 13 | } = { 14 | encode: 'base64' 15 | } 16 | 17 | function importKey(pub: string): Promise { 18 | const token = jwk(pub) 19 | const promise = crypto.subtle.importKey('jwk', token, ecdsa.pair, false, [ 20 | 'verify' 21 | ]) 22 | return promise 23 | } 24 | 25 | export async function verifyHashSignature( 26 | hash: string, 27 | signature: string, 28 | pub: string, 29 | opt = DEFAULT_OPTS 30 | ): Promise { 31 | const encoding = opt.encode || DEFAULT_OPTS.encode 32 | const key = await importKey(pub) 33 | // @ts-ignore 34 | const buf = Buffer.from(signature, encoding) 35 | const sig = new Uint8Array(buf) 36 | 37 | if ( 38 | await crypto.subtle.verify( 39 | ecdsa.sign, 40 | key, 41 | sig, 42 | new Uint8Array(Buffer.from(hash, 'hex')) 43 | ) 44 | ) { 45 | return true 46 | } 47 | 48 | return false 49 | } 50 | 51 | export async function verifySignature( 52 | text: string, 53 | signature: string, 54 | pub: string, 55 | opt = DEFAULT_OPTS 56 | ): Promise { 57 | const hash = await sha256( 58 | typeof text === 'string' ? text : JSON.stringify(text) 59 | ) 60 | return verifyHashSignature(hash.toString('hex'), signature, pub, opt) 61 | } 62 | 63 | export async function verify( 64 | data: string | { readonly m: string; readonly s: string }, 65 | pub: string, 66 | opt = DEFAULT_OPTS 67 | ): Promise { 68 | const json = parse(data) 69 | if (await verifySignature(json.m, json.s, pub, opt)) { 70 | return true 71 | } 72 | if (opt.fallback) { 73 | return oldVerify(data, pub, opt) 74 | } 75 | return false 76 | } 77 | 78 | export async function oldVerify( 79 | _data: string | { readonly m: string; readonly s: string }, 80 | _pub: string, 81 | _opt = DEFAULT_OPTS 82 | ): Promise { 83 | throw new Error('Legacy fallback validation not yet supported') 84 | } 85 | -------------------------------------------------------------------------------- /packages/sear/src/work.ts: -------------------------------------------------------------------------------- 1 | import { pbkdf2 } from './settings' 2 | import { Buffer, crypto, TextEncoder } from './shims' 3 | 4 | const DEFAULT_OPTS = { 5 | encode: 'base64', 6 | hash: pbkdf2.hash, 7 | name: 'PBKDF2' 8 | } 9 | 10 | export async function work( 11 | data: string, 12 | salt: string, 13 | opt: { 14 | readonly name?: string 15 | readonly iterations?: number 16 | readonly hash?: { readonly name: string } 17 | readonly encode?: string 18 | readonly length?: number 19 | } = DEFAULT_OPTS 20 | ): Promise { 21 | const key = await crypto.subtle.importKey( 22 | 'raw', 23 | new TextEncoder().encode(data), 24 | { name: opt.name || DEFAULT_OPTS.name || '' }, 25 | false, 26 | ['deriveBits'] 27 | ) 28 | const res = await crypto.subtle.deriveBits( 29 | { 30 | hash: opt.hash || DEFAULT_OPTS.hash, 31 | iterations: opt.iterations || pbkdf2.iter, 32 | name: opt.name || 'PBKDF2', 33 | salt: new TextEncoder().encode(salt) 34 | }, 35 | key, 36 | opt.length || pbkdf2.ks * 8 37 | ) 38 | return Buffer.from(res, 'binary').toString(opt.encode || DEFAULT_OPTS.encode) 39 | } 40 | -------------------------------------------------------------------------------- /packages/sear/tests/encrypt.test.ts: -------------------------------------------------------------------------------- 1 | import { pair as createPair } from '../src/pair' 2 | import { encrypt } from '../src/encrypt' 3 | import { decrypt } from '../src/decrypt' 4 | 5 | describe('encrypt', () => { 6 | it('encrypts data that can be decrypted', async () => { 7 | const pair = await createPair() 8 | const data = 'foo' 9 | const ciphertext = (await encrypt(data, pair.epriv)) as string 10 | expect(await decrypt(ciphertext, pair.epriv)).toBe(data) 11 | }) 12 | }) 13 | -------------------------------------------------------------------------------- /packages/sear/tests/gun-sear.test.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Dummy test 3 | */ 4 | describe('Dummy test', () => { 5 | it('works if true is truthy', () => { 6 | expect(true).toBeTruthy() 7 | }) 8 | }) 9 | -------------------------------------------------------------------------------- /packages/sear/tests/sign.test.ts: -------------------------------------------------------------------------------- 1 | import { pair as createPair } from '../src/pair' 2 | import { sign } from '../src/sign' 3 | import { verify } from '../src/verify' 4 | 5 | describe('sign', () => { 6 | it('signs data that can be verified', async () => { 7 | const pair = await createPair() 8 | const otherPair = await createPair() 9 | const data = 'foo' 10 | const signed = await sign(data, pair) 11 | expect(await verify(signed, pair.pub)).toBe(true) 12 | expect(await verify(signed, otherPair.pub)).toBe(false) 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /packages/sear/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "outDir": "build/main", 5 | "rootDir": "src", 6 | "moduleResolution": "node", 7 | "module": "commonjs", 8 | "declaration": true, 9 | "inlineSourceMap": true, 10 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, 11 | 12 | "strict": true /* Enable all strict type-checking options. */, 13 | 14 | /* Strict Type-Checking Options */ 15 | // "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, 16 | // "strictNullChecks": true /* Enable strict null checks. */, 17 | // "strictFunctionTypes": true /* Enable strict checking of function types. */, 18 | // "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */, 19 | // "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, 20 | // "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, 21 | 22 | /* Additional Checks */ 23 | "skipLibCheck": true, 24 | "noUnusedLocals": true /* Report errors on unused locals. */, 25 | "noUnusedParameters": true /* Report errors on unused parameters. */, 26 | "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, 27 | "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, 28 | 29 | /* Debugging Options */ 30 | "traceResolution": false /* Report module resolution log messages. */, 31 | "listEmittedFiles": false /* Print names of generated files part of the compilation. */, 32 | "listFiles": false /* Print names of files part of the compilation. */, 33 | "pretty": true /* Stylize errors and messages using color and context. */, 34 | 35 | /* Experimental Options */ 36 | // "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, 37 | // "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, 38 | 39 | "lib": ["es2017", "dom"], 40 | "types": ["node", "jest"], 41 | "typeRoots": ["node_modules/@types", "src/types"] 42 | }, 43 | "include": ["src/**/*.ts"], 44 | "exclude": ["node_modules/**"], 45 | "compileOnSave": false 46 | } 47 | -------------------------------------------------------------------------------- /packages/sear/tsconfig.module.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "outDir": "build/module", 6 | "module": "esnext" 7 | }, 8 | "exclude": [ 9 | "node_modules/**" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/sear/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["tslint:latest", "tslint-config-prettier", "tslint-immutable"], 3 | "rules": { 4 | "variable-name": false, 5 | "interface-name": [true, "never-prefix"], 6 | "no-implicit-dependencies": [true, "dev"], 7 | 8 | "no-var-keyword": true, 9 | "no-parameter-reassignment": true, 10 | "typedef": [true, "call-signature"], 11 | 12 | "readonly-keyword": true, 13 | "readonly-array": true, 14 | "no-let": true, 15 | "no-object-mutation": true, 16 | "no-delete": true, 17 | "no-method-signature": true, 18 | 19 | "no-this": true, 20 | "no-class": true, 21 | "no-mixed-interface": true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/socketcluster-connector/.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # https://circleci.com/docs/2.0/language-javascript/ 2 | version: 2 3 | jobs: 4 | 'node-10': 5 | docker: 6 | - image: circleci/node:10 7 | working_directory: ~/typescript-starter 8 | steps: 9 | - checkout 10 | # Download and cache dependencies 11 | - restore_cache: 12 | keys: 13 | - v1-dependencies-{{ checksum "package.json" }} 14 | # fallback to using the latest cache if no exact match is found 15 | - v1-dependencies- 16 | - run: npm install 17 | - save_cache: 18 | paths: 19 | - node_modules 20 | key: v1-dependencies-{{ checksum "package.json" }} 21 | - run: npm test 22 | - run: npm run cov:send 23 | - run: npm run cov:check 24 | 'node-latest': 25 | docker: 26 | - image: circleci/node:latest 27 | working_directory: ~/typescript-starter 28 | steps: 29 | - checkout 30 | - restore_cache: 31 | keys: 32 | - v1-dependencies-{{ checksum "package.json" }} 33 | - v1-dependencies- 34 | - run: npm install 35 | - save_cache: 36 | paths: 37 | - node_modules 38 | key: v1-dependencies-{{ checksum "package.json" }} 39 | - run: npm test 40 | - run: npm run cov:send 41 | - run: npm run cov:check 42 | 43 | workflows: 44 | version: 2 45 | build: 46 | jobs: 47 | - 'node-10' 48 | - 'node-latest' 49 | -------------------------------------------------------------------------------- /packages/socketcluster-connector/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | max_line_length = 80 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | max_line_length = 0 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /packages/socketcluster-connector/.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Example Contributing Guidelines 2 | 3 | This is an example of GitHub's contributing guidelines file. Check out GitHub's [CONTRIBUTING.md help center article](https://help.github.com/articles/setting-guidelines-for-repository-contributors/) for more information. 4 | -------------------------------------------------------------------------------- /packages/socketcluster-connector/.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **I'm submitting a ...** 2 | [ ] bug report 3 | [ ] feature request 4 | [ ] question about the decisions made in the repository 5 | [ ] question about how to use this project 6 | 7 | * **Summary** 8 | 9 | 10 | 11 | * **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.) 12 | -------------------------------------------------------------------------------- /packages/socketcluster-connector/.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...) 2 | 3 | 4 | 5 | * **What is the current behavior?** (You can also link to an open issue here) 6 | 7 | 8 | 9 | * **What is the new behavior (if this is a feature change)?** 10 | 11 | 12 | 13 | * **Other information**: 14 | -------------------------------------------------------------------------------- /packages/socketcluster-connector/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | test 4 | src/**.js 5 | .idea/* 6 | 7 | coverage 8 | .nyc_output 9 | *.log 10 | 11 | package-lock.json -------------------------------------------------------------------------------- /packages/socketcluster-connector/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | tsconfig.json 4 | tsconfig.module.json 5 | tslint.json 6 | .travis.yml 7 | .github 8 | .prettierignore 9 | .vscode 10 | build/docs 11 | **/*.spec.* 12 | coverage 13 | .nyc_output 14 | *.log 15 | -------------------------------------------------------------------------------- /packages/socketcluster-connector/.prettierignore: -------------------------------------------------------------------------------- 1 | # package.json is formatted by package managers, so we ignore it here 2 | package.json -------------------------------------------------------------------------------- /packages/socketcluster-connector/.vscode/debug-ts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const meow = require('meow'); 3 | const path = require('path'); 4 | 5 | const tsFile = getTSFile(); 6 | const jsFile = TS2JS(tsFile); 7 | 8 | replaceCLIArg(tsFile, jsFile); 9 | 10 | // Ava debugger 11 | require('ava/profile'); 12 | 13 | /** 14 | * get ts file path from CLI args 15 | * 16 | * @return string path 17 | */ 18 | function getTSFile() { 19 | const cli = meow(); 20 | return cli.input[0]; 21 | } 22 | 23 | /** 24 | * get associated compiled js file path 25 | * 26 | * @param tsFile path 27 | * @return string path 28 | */ 29 | function TS2JS(tsFile) { 30 | const srcFolder = path.join(__dirname, '..', 'src'); 31 | const distFolder = path.join(__dirname, '..', 'build', 'main'); 32 | 33 | const tsPathObj = path.parse(tsFile); 34 | 35 | return path.format({ 36 | dir: tsPathObj.dir.replace(srcFolder, distFolder), 37 | ext: '.js', 38 | name: tsPathObj.name, 39 | root: tsPathObj.root 40 | }); 41 | } 42 | 43 | /** 44 | * replace a value in CLI args 45 | * 46 | * @param search value to search 47 | * @param replace value to replace 48 | * @return void 49 | */ 50 | function replaceCLIArg(search, replace) { 51 | process.argv[process.argv.indexOf(search)] = replace; 52 | } -------------------------------------------------------------------------------- /packages/socketcluster-connector/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [{ 4 | "type": "node", 5 | "request": "launch", 6 | "name": "Debug Project", 7 | // we test in `build` to make cleanup fast and easy 8 | "cwd": "${workspaceFolder}/build", 9 | // Replace this with your project root. If there are multiple, you can 10 | // automatically run the currently visible file with: "program": ${file}" 11 | "program": "${workspaceFolder}/src/cli/cli.ts", 12 | // "args": ["--no-install"], 13 | "outFiles": ["${workspaceFolder}/build/main/**/*.js"], 14 | "skipFiles": [ 15 | "/**/*.js", 16 | "${workspaceFolder}/node_modules/**/*.js" 17 | ], 18 | "preLaunchTask": "npm: build", 19 | "stopOnEntry": true, 20 | "smartStep": true, 21 | "runtimeArgs": ["--nolazy"], 22 | "env": { 23 | "TYPESCRIPT_STARTER_REPO_URL": "${workspaceFolder}" 24 | }, 25 | "console": "externalTerminal" 26 | }, 27 | { 28 | "type": "node", 29 | "request": "launch", 30 | "name": "Debug Spec", 31 | "program": "${workspaceRoot}/.vscode/debug-ts.js", 32 | "args": ["${file}"], 33 | "skipFiles": ["/**/*.js"], 34 | // Consider using `npm run watch` or `yarn watch` for faster debugging 35 | // "preLaunchTask": "npm: build", 36 | // "smartStep": true, 37 | "runtimeArgs": ["--nolazy"] 38 | }] 39 | } -------------------------------------------------------------------------------- /packages/socketcluster-connector/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib" 3 | // "typescript.implementationsCodeLens.enabled": true 4 | // "typescript.referencesCodeLens.enabled": true 5 | } 6 | -------------------------------------------------------------------------------- /packages/socketcluster-connector/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 go1dfish 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/socketcluster-connector/README.md: -------------------------------------------------------------------------------- 1 | # @notabug/chaingun-socket-cluster-connector 2 | 3 | ChainGun Graph Connector for Socket Cluster 4 | -------------------------------------------------------------------------------- /packages/socketcluster-connector/src/index.ts: -------------------------------------------------------------------------------- 1 | import { SocketClusterGraphConnector } from "./SocketClusterGraphConnector" 2 | 3 | export default SocketClusterGraphConnector 4 | -------------------------------------------------------------------------------- /packages/socketcluster-connector/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "outDir": "build/main", 5 | "rootDir": "src", 6 | "moduleResolution": "node", 7 | "module": "commonjs", 8 | "declaration": true, 9 | "inlineSourceMap": true, 10 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, 11 | "strict": true /* Enable all strict type-checking options. */, 12 | /* Strict Type-Checking Options */ 13 | // "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, 14 | // "strictNullChecks": true /* Enable strict null checks. */, 15 | // "strictFunctionTypes": true /* Enable strict checking of function types. */, 16 | // "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */, 17 | // "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, 18 | // "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, 19 | /* Additional Checks */ 20 | "noUnusedLocals": true /* Report errors on unused locals. */, 21 | "noUnusedParameters": true /* Report errors on unused parameters. */, 22 | "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, 23 | "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, 24 | /* Debugging Options */ 25 | "traceResolution": false /* Report module resolution log messages. */, 26 | "listEmittedFiles": false /* Print names of generated files part of the compilation. */, 27 | "listFiles": false /* Print names of files part of the compilation. */, 28 | "pretty": true /* Stylize errors and messages using color and context. */, 29 | "skipLibCheck": true, 30 | /* Experimental Options */ 31 | // "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, 32 | // "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, 33 | "lib": [ 34 | "es2017" 35 | ], 36 | "types": [], 37 | "typeRoots": [ 38 | "node_modules/@types", 39 | "src/types" 40 | ] 41 | }, 42 | "include": [ 43 | "src/**/*.ts" 44 | ], 45 | "exclude": [ 46 | "node_modules/**" 47 | ], 48 | "compileOnSave": false 49 | } -------------------------------------------------------------------------------- /packages/socketcluster-connector/tsconfig.module.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "outDir": "build/module", 6 | "module": "esnext" 7 | }, 8 | "exclude": [ 9 | "node_modules/**" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/socketcluster-connector/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["tslint:latest", "tslint-config-prettier", "tslint-immutable"], 3 | "rules": { 4 | "variable-name": false, 5 | "interface-name": [true, "never-prefix"], 6 | "no-implicit-dependencies": [true, "dev"], 7 | 8 | "no-var-keyword": true, 9 | "no-parameter-reassignment": true, 10 | "typedef": [true, "call-signature"], 11 | 12 | "readonly-keyword": true, 13 | "readonly-array": true, 14 | "no-let": true, 15 | "no-object-mutation": true, 16 | "no-delete": true, 17 | "no-method-signature": true 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/socketcluster-worker/.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # https://circleci.com/docs/2.0/language-javascript/ 2 | version: 2 3 | jobs: 4 | 'node-10': 5 | docker: 6 | - image: circleci/node:10 7 | working_directory: ~/typescript-starter 8 | steps: 9 | - checkout 10 | # Download and cache dependencies 11 | - restore_cache: 12 | keys: 13 | - v1-dependencies-{{ checksum "package.json" }} 14 | # fallback to using the latest cache if no exact match is found 15 | - v1-dependencies- 16 | - run: npm install 17 | - save_cache: 18 | paths: 19 | - node_modules 20 | key: v1-dependencies-{{ checksum "package.json" }} 21 | - run: npm test 22 | - run: npm run cov:send 23 | - run: npm run cov:check 24 | 'node-latest': 25 | docker: 26 | - image: circleci/node:latest 27 | working_directory: ~/typescript-starter 28 | steps: 29 | - checkout 30 | - restore_cache: 31 | keys: 32 | - v1-dependencies-{{ checksum "package.json" }} 33 | - v1-dependencies- 34 | - run: npm install 35 | - save_cache: 36 | paths: 37 | - node_modules 38 | key: v1-dependencies-{{ checksum "package.json" }} 39 | - run: npm test 40 | - run: npm run cov:send 41 | - run: npm run cov:check 42 | 43 | workflows: 44 | version: 2 45 | build: 46 | jobs: 47 | - 'node-10' 48 | - 'node-latest' 49 | -------------------------------------------------------------------------------- /packages/socketcluster-worker/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | max_line_length = 80 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | max_line_length = 0 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /packages/socketcluster-worker/.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Example Contributing Guidelines 2 | 3 | This is an example of GitHub's contributing guidelines file. Check out GitHub's [CONTRIBUTING.md help center article](https://help.github.com/articles/setting-guidelines-for-repository-contributors/) for more information. 4 | -------------------------------------------------------------------------------- /packages/socketcluster-worker/.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **I'm submitting a ...** 2 | [ ] bug report 3 | [ ] feature request 4 | [ ] question about the decisions made in the repository 5 | [ ] question about how to use this project 6 | 7 | * **Summary** 8 | 9 | 10 | 11 | * **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.) 12 | -------------------------------------------------------------------------------- /packages/socketcluster-worker/.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...) 2 | 3 | 4 | 5 | * **What is the current behavior?** (You can also link to an open issue here) 6 | 7 | 8 | 9 | * **What is the new behavior (if this is a feature change)?** 10 | 11 | 12 | 13 | * **Other information**: 14 | -------------------------------------------------------------------------------- /packages/socketcluster-worker/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | test 4 | src/**.js 5 | .idea/* 6 | 7 | coverage 8 | .nyc_output 9 | *.log 10 | 11 | package-lock.json -------------------------------------------------------------------------------- /packages/socketcluster-worker/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | tsconfig.json 4 | tsconfig.module.json 5 | tslint.json 6 | .travis.yml 7 | .github 8 | .prettierignore 9 | .vscode 10 | build/docs 11 | **/*.spec.* 12 | coverage 13 | .nyc_output 14 | *.log 15 | -------------------------------------------------------------------------------- /packages/socketcluster-worker/.prettierignore: -------------------------------------------------------------------------------- 1 | # package.json is formatted by package managers, so we ignore it here 2 | package.json -------------------------------------------------------------------------------- /packages/socketcluster-worker/.vscode/debug-ts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const meow = require('meow'); 3 | const path = require('path'); 4 | 5 | const tsFile = getTSFile(); 6 | const jsFile = TS2JS(tsFile); 7 | 8 | replaceCLIArg(tsFile, jsFile); 9 | 10 | // Ava debugger 11 | require('ava/profile'); 12 | 13 | /** 14 | * get ts file path from CLI args 15 | * 16 | * @return string path 17 | */ 18 | function getTSFile() { 19 | const cli = meow(); 20 | return cli.input[0]; 21 | } 22 | 23 | /** 24 | * get associated compiled js file path 25 | * 26 | * @param tsFile path 27 | * @return string path 28 | */ 29 | function TS2JS(tsFile) { 30 | const srcFolder = path.join(__dirname, '..', 'src'); 31 | const distFolder = path.join(__dirname, '..', 'build', 'main'); 32 | 33 | const tsPathObj = path.parse(tsFile); 34 | 35 | return path.format({ 36 | dir: tsPathObj.dir.replace(srcFolder, distFolder), 37 | ext: '.js', 38 | name: tsPathObj.name, 39 | root: tsPathObj.root 40 | }); 41 | } 42 | 43 | /** 44 | * replace a value in CLI args 45 | * 46 | * @param search value to search 47 | * @param replace value to replace 48 | * @return void 49 | */ 50 | function replaceCLIArg(search, replace) { 51 | process.argv[process.argv.indexOf(search)] = replace; 52 | } -------------------------------------------------------------------------------- /packages/socketcluster-worker/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [{ 4 | "type": "node", 5 | "request": "launch", 6 | "name": "Debug Project", 7 | // we test in `build` to make cleanup fast and easy 8 | "cwd": "${workspaceFolder}/build", 9 | // Replace this with your project root. If there are multiple, you can 10 | // automatically run the currently visible file with: "program": ${file}" 11 | "program": "${workspaceFolder}/src/cli/cli.ts", 12 | // "args": ["--no-install"], 13 | "outFiles": ["${workspaceFolder}/build/main/**/*.js"], 14 | "skipFiles": [ 15 | "/**/*.js", 16 | "${workspaceFolder}/node_modules/**/*.js" 17 | ], 18 | "preLaunchTask": "npm: build", 19 | "stopOnEntry": true, 20 | "smartStep": true, 21 | "runtimeArgs": ["--nolazy"], 22 | "env": { 23 | "TYPESCRIPT_STARTER_REPO_URL": "${workspaceFolder}" 24 | }, 25 | "console": "externalTerminal" 26 | }, 27 | { 28 | "type": "node", 29 | "request": "launch", 30 | "name": "Debug Spec", 31 | "program": "${workspaceRoot}/.vscode/debug-ts.js", 32 | "args": ["${file}"], 33 | "skipFiles": ["/**/*.js"], 34 | // Consider using `npm run watch` or `yarn watch` for faster debugging 35 | // "preLaunchTask": "npm: build", 36 | // "smartStep": true, 37 | "runtimeArgs": ["--nolazy"] 38 | }] 39 | } -------------------------------------------------------------------------------- /packages/socketcluster-worker/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib" 3 | // "typescript.implementationsCodeLens.enabled": true 4 | // "typescript.referencesCodeLens.enabled": true 5 | } 6 | -------------------------------------------------------------------------------- /packages/socketcluster-worker/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 go1dfish 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/socketcluster-worker/README.md: -------------------------------------------------------------------------------- 1 | # @notabug/gun-socketcluster-worker 2 | 3 | SocketCluster Worker supporting gunDB protocol -------------------------------------------------------------------------------- /packages/socketcluster-worker/src/config.ts: -------------------------------------------------------------------------------- 1 | export const PEERS_CONFIG_FILE = process.env.PEERS_CONFIG_FILE || './peers.yaml' 2 | 3 | export const PEER_SYNC_INTERVAL = readInt(process.env.PEER_SYNC_INTERVAL, 1000) 4 | export const PEER_BACK_SYNC = readInt(process.env.PEER_BACK_SYNC, 0) 5 | export const PEER_MAX_STALENESS = readInt(process.env.PEER_MAX_STALENESS) 6 | export const PEER_BATCH_INTERVAL = readInt(process.env.PEER_BATCH_INTERVAL) 7 | 8 | export const PEER_PRUNE_INTERVAL = readInt( 9 | process.env.PEER_PRUNE_INTERVAL, 10 | 60 * 60 * 1000 11 | ) 12 | 13 | export const PEER_CHANGELOG_RETENTION = readInt( 14 | process.env.PEER_CHANGELOG_RETENTION, 15 | 24 * 60 * 60 * 1000 16 | ) 17 | 18 | export const SSE_PING_INTERVAL = readInt( 19 | process.env.SSE_PING_INTERVAL, 20 | 30 * 1000 21 | ) 22 | 23 | function readInt(val?: string, defValue?: number): number | undefined { 24 | const parsed = parseInt(val, 10) 25 | return parsed || parsed === 0 ? parsed : defValue 26 | } 27 | -------------------------------------------------------------------------------- /packages/socketcluster-worker/src/index.ts: -------------------------------------------------------------------------------- 1 | import { GunSocketClusterWorker } from "./GunSocketClusterWorker" 2 | 3 | export default GunSocketClusterWorker 4 | -------------------------------------------------------------------------------- /packages/socketcluster-worker/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "outDir": "build/main", 5 | "rootDir": "src", 6 | "moduleResolution": "node", 7 | "module": "commonjs", 8 | "declaration": true, 9 | "inlineSourceMap": true, 10 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, 11 | // "strict": true /* Enable all strict type-checking options. */, 12 | /* Strict Type-Checking Options */ 13 | // "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, 14 | // "strictNullChecks": true /* Enable strict null checks. */, 15 | // "strictFunctionTypes": true /* Enable strict checking of function types. */, 16 | // "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */, 17 | // "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, 18 | // "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, 19 | /* Additional Checks */ 20 | "skipLibCheck": true, 21 | "noUnusedLocals": true /* Report errors on unused locals. */, 22 | "noUnusedParameters": true /* Report errors on unused parameters. */, 23 | "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, 24 | "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, 25 | /* Debugging Options */ 26 | "traceResolution": false /* Report module resolution log messages. */, 27 | "listEmittedFiles": false /* Print names of generated files part of the compilation. */, 28 | "listFiles": false /* Print names of files part of the compilation. */, 29 | "pretty": true /* Stylize errors and messages using color and context. */, 30 | /* Experimental Options */ 31 | // "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, 32 | // "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, 33 | "lib": [ 34 | "es2017" 35 | ], 36 | "types": [ 37 | "node" 38 | ], 39 | "typeRoots": [ 40 | "node_modules/@types", 41 | "src/types" 42 | ] 43 | }, 44 | "include": [ 45 | "src/**/*.ts" 46 | ], 47 | "exclude": [ 48 | "node_modules/**" 49 | ], 50 | "compileOnSave": false 51 | } -------------------------------------------------------------------------------- /packages/socketcluster-worker/tsconfig.module.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "outDir": "build/module", 6 | "module": "esnext" 7 | }, 8 | "exclude": [ 9 | "node_modules/**" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/socketcluster-worker/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["tslint:latest", "tslint-config-prettier", "tslint-immutable"], 3 | "rules": { 4 | "interface-name": [true, "never-prefix"], 5 | // TODO: allow devDependencies only in **/*.spec.ts files: 6 | // waiting on https://github.com/palantir/tslint/pull/3708 7 | "no-implicit-dependencies": [true, "dev"], 8 | 9 | /* tslint-immutable rules */ 10 | // Recommended built-in rules 11 | "no-var-keyword": true, 12 | "no-parameter-reassignment": true, 13 | "typedef": [true, "call-signature"], 14 | 15 | // Immutability rules 16 | "readonly-keyword": true, 17 | "readonly-array": true, 18 | "no-let": true, 19 | "no-object-mutation": true, 20 | "no-delete": true, 21 | "no-method-signature": true 22 | 23 | /* end tslint-immutable rules */ 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/suppressor-sear/.editorconfig: -------------------------------------------------------------------------------- 1 | #root = true 2 | 3 | [*] 4 | indent_style = space 5 | end_of_line = lf 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | max_line_length = 100 10 | indent_size = 2 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /packages/suppressor-sear/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | .nyc_output 4 | .DS_Store 5 | *.log 6 | .vscode 7 | .idea 8 | dist 9 | compiled 10 | .awcache 11 | .rpt2_cache 12 | docs 13 | -------------------------------------------------------------------------------- /packages/suppressor-sear/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | cache: 3 | directories: 4 | - ~/.npm 5 | notifications: 6 | email: false 7 | node_js: 8 | - '10' 9 | - '11' 10 | - '8' 11 | - '6' 12 | script: 13 | - npm run test:prod && npm run build 14 | after_success: 15 | - npm run travis-deploy-once "npm run report-coverage" 16 | - if [ "$TRAVIS_BRANCH" = "master" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then npm run travis-deploy-once "npm run deploy-docs"; fi 17 | - if [ "$TRAVIS_BRANCH" = "master" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then npm run travis-deploy-once "npm run semantic-release"; fi 18 | branches: 19 | except: 20 | - /^v\d+\.\d+\.\d+$/ 21 | -------------------------------------------------------------------------------- /packages/suppressor-sear/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 go1dfish 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packages/suppressor-sear/code-of-conduct.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | ## Free Speech and Consideration 4 | 5 | Everyone has the right to communicate opinions and ideas without fear of censorship. Consideration shall be given to all constructive speech that is based in fact and reason. 6 | -------------------------------------------------------------------------------- /packages/suppressor-sear/rollup.config.ts: -------------------------------------------------------------------------------- 1 | import resolve from 'rollup-plugin-node-resolve' 2 | import commonjs from 'rollup-plugin-commonjs' 3 | import sourceMaps from 'rollup-plugin-sourcemaps' 4 | import camelCase from 'lodash.camelcase' 5 | import typescript from 'rollup-plugin-typescript2' 6 | import json from 'rollup-plugin-json' 7 | 8 | const pkg = require('./package.json') 9 | 10 | const libraryName = '@chaingun/suppressor-sear' 11 | 12 | export default { 13 | input: `src/${libraryName}.ts`, 14 | output: [ 15 | { file: pkg.main, name: camelCase(libraryName), format: 'umd', sourcemap: true }, 16 | { file: pkg.module, format: 'es', sourcemap: true } 17 | ], 18 | // Indicate here external modules you don't wanna include in your bundle (i.e.: 'lodash') 19 | external: ['@notabug/gun-suppressor', 'ramda', 'route-parser'], 20 | watch: { 21 | include: 'src/**' 22 | }, 23 | plugins: [ 24 | // Allow json resolution 25 | json(), 26 | // Compile TypeScript files 27 | typescript({ useTsconfigDeclarationDir: true }), 28 | // Allow bundling cjs modules (unlike webpack, rollup doesn't understand cjs) 29 | commonjs(), 30 | // Allow node_modules resolution, so you can use 'external' to control 31 | // which external modules to include in the bundle 32 | // https://github.com/rollup/rollup-plugin-node-resolve#usage 33 | resolve(), 34 | 35 | // Resolve source maps to the original source 36 | sourceMaps() 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /packages/suppressor-sear/tools/gh-pages-publish.ts: -------------------------------------------------------------------------------- 1 | const { cd, exec, echo, touch } = require("shelljs") 2 | const { readFileSync } = require("fs") 3 | const url = require("url") 4 | 5 | let repoUrl 6 | let pkg = JSON.parse(readFileSync("package.json") as any) 7 | if (typeof pkg.repository === "object") { 8 | if (!pkg.repository.hasOwnProperty("url")) { 9 | throw new Error("URL does not exist in repository section") 10 | } 11 | repoUrl = pkg.repository.url 12 | } else { 13 | repoUrl = pkg.repository 14 | } 15 | 16 | let parsedUrl = url.parse(repoUrl) 17 | let repository = (parsedUrl.host || "") + (parsedUrl.path || "") 18 | let ghToken = process.env.GH_TOKEN 19 | 20 | echo("Deploying docs!!!") 21 | cd("docs") 22 | touch(".nojekyll") 23 | exec("git init") 24 | exec("git add .") 25 | exec('git config user.name "go1dfish"') 26 | exec('git config user.email "me@go1dfish.me"') 27 | exec('git commit -m "docs(docs): update gh-pages"') 28 | exec( 29 | `git push --force --quiet "https://${ghToken}@${repository}" master:gh-pages` 30 | ) 31 | echo("Docs deployed!!") 32 | -------------------------------------------------------------------------------- /packages/suppressor-sear/tools/semantic-release-prepare.ts: -------------------------------------------------------------------------------- 1 | const path = require("path") 2 | const { fork } = require("child_process") 3 | const colors = require("colors") 4 | 5 | const { readFileSync, writeFileSync } = require("fs") 6 | const pkg = JSON.parse( 7 | readFileSync(path.resolve(__dirname, "..", "package.json")) 8 | ) 9 | 10 | pkg.scripts.prepush = "npm run test:prod && npm run build" 11 | pkg.scripts.commitmsg = "commitlint -E HUSKY_GIT_PARAMS" 12 | 13 | writeFileSync( 14 | path.resolve(__dirname, "..", "package.json"), 15 | JSON.stringify(pkg, null, 2) 16 | ) 17 | 18 | // Call husky to set up the hooks 19 | fork(path.resolve(__dirname, "..", "node_modules", "husky", "lib", "installer", 'bin'), ['install']) 20 | 21 | console.log() 22 | console.log(colors.green("Done!!")) 23 | console.log() 24 | 25 | if (pkg.repository.url.trim()) { 26 | console.log(colors.cyan("Now run:")) 27 | console.log(colors.cyan(" npm install -g semantic-release-cli")) 28 | console.log(colors.cyan(" semantic-release-cli setup")) 29 | console.log() 30 | console.log( 31 | colors.cyan('Important! Answer NO to "Generate travis.yml" question') 32 | ) 33 | console.log() 34 | console.log( 35 | colors.gray( 36 | 'Note: Make sure "repository.url" in your package.json is correct before' 37 | ) 38 | ) 39 | } else { 40 | console.log( 41 | colors.red( 42 | 'First you need to set the "repository.url" property in package.json' 43 | ) 44 | ) 45 | console.log(colors.cyan("Then run:")) 46 | console.log(colors.cyan(" npm install -g semantic-release-cli")) 47 | console.log(colors.cyan(" semantic-release-cli setup")) 48 | console.log() 49 | console.log( 50 | colors.cyan('Important! Answer NO to "Generate travis.yml" question') 51 | ) 52 | } 53 | 54 | console.log() 55 | -------------------------------------------------------------------------------- /packages/suppressor-sear/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "moduleResolution": "node", 4 | "target": "es5", 5 | "module":"es2015", 6 | "lib": ["es2015", "es2016", "es2017", "dom"], 7 | "strict": true, 8 | "sourceMap": true, 9 | "declaration": true, 10 | "allowSyntheticDefaultImports": true, 11 | "experimentalDecorators": true, 12 | "emitDecoratorMetadata": true, 13 | "declarationDir": "dist/types", 14 | "outDir": "dist/lib", 15 | "typeRoots": [ 16 | "node_modules/@types" 17 | ] 18 | }, 19 | "include": [ 20 | "src" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /packages/suppressor-sear/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "tslint-config-standard", 4 | "tslint-config-prettier" 5 | ] 6 | } -------------------------------------------------------------------------------- /packages/suppressor/.editorconfig: -------------------------------------------------------------------------------- 1 | #root = true 2 | 3 | [*] 4 | indent_style = space 5 | end_of_line = lf 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | max_line_length = 100 10 | indent_size = 2 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /packages/suppressor/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | .nyc_output 4 | .DS_Store 5 | *.log 6 | .vscode 7 | .idea 8 | dist 9 | compiled 10 | .awcache 11 | .rpt2_cache 12 | docs 13 | -------------------------------------------------------------------------------- /packages/suppressor/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | cache: 3 | directories: 4 | - ~/.npm 5 | notifications: 6 | email: false 7 | node_js: 8 | - '10' 9 | - '11' 10 | - '8' 11 | - '6' 12 | script: 13 | - npm run test:prod && npm run build 14 | after_success: 15 | - npm run travis-deploy-once "npm run report-coverage" 16 | - if [ "$TRAVIS_BRANCH" = "master" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then npm run travis-deploy-once "npm run deploy-docs"; fi 17 | - if [ "$TRAVIS_BRANCH" = "master" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then npm run travis-deploy-once "npm run semantic-release"; fi 18 | branches: 19 | except: 20 | - /^v\d+\.\d+\.\d+$/ 21 | -------------------------------------------------------------------------------- /packages/suppressor/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 go1dfish 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packages/suppressor/README.md: -------------------------------------------------------------------------------- 1 | # gun-suppressor 2 | 3 | JSON-Schema based validation for gunDB using ajv. 4 | 5 | Built with https://github.com/krasimir/webpack-library-starter 6 | -------------------------------------------------------------------------------- /packages/suppressor/code-of-conduct.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | ## Free Speech and Consideration 4 | 5 | Everyone has the right to communicate opinions and ideas without fear of censorship. Consideration shall be given to all constructive speech that is based in fact and reason. 6 | -------------------------------------------------------------------------------- /packages/suppressor/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@chaingun/suppressor", 3 | "version": "0.23.7", 4 | "description": "JSON Schema validation for gunDB with ajv", 5 | "main": "dist/@chaingun/suppressor.umd.js", 6 | "module": "dist/@chaingun/suppressor.es5.js", 7 | "typings": "dist/types/gun-suppressor.d.ts", 8 | "files": [ 9 | "dist" 10 | ], 11 | "author": "go1dfish ", 12 | "keywords": [ 13 | "gundb", 14 | "json-schema" 15 | ], 16 | "license": "MIT", 17 | "engines": { 18 | "node": ">=6.0.0" 19 | }, 20 | "scripts": { 21 | "lint": "tslint --project tsconfig.json -t codeFrame 'src/**/*.ts' 'test/**/*.ts'", 22 | "prebuild": "rimraf dist", 23 | "build": "tsc --module commonjs && rollup -c rollup.config.ts", 24 | "buildwdocs": "tsc --module commonjs && rollup -c rollup.config.ts && typedoc --out docs --target es6 --theme minimal --mode file src", 25 | "start": "rollup -c rollup.config.ts -w", 26 | "test": "jest --coverage", 27 | "test:watch": "jest --coverage --watch", 28 | "test:prod": "npm run lint && npm run test -- --no-cache", 29 | "deploy-docs": "ts-node tools/gh-pages-publish", 30 | "report-coverage": "cat ./coverage/lcov.info | coveralls", 31 | "travis-deploy-once": "travis-deploy-once" 32 | }, 33 | "jest": { 34 | "transform": { 35 | ".(ts|tsx)": "ts-jest" 36 | }, 37 | "testEnvironment": "node", 38 | "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$", 39 | "moduleFileExtensions": [ 40 | "ts", 41 | "tsx", 42 | "js" 43 | ], 44 | "coveragePathIgnorePatterns": [ 45 | "/node_modules/", 46 | "/test/" 47 | ], 48 | "coverageThreshold": { 49 | "global": { 50 | "branches": 90, 51 | "functions": 95, 52 | "lines": 95, 53 | "statements": 95 54 | } 55 | }, 56 | "collectCoverageFrom": [ 57 | "src/*.{js,ts}" 58 | ] 59 | }, 60 | "prettier": { 61 | "semi": false, 62 | "singleQuote": true 63 | }, 64 | "devDependencies": { 65 | "@commitlint/cli": "^7.1.2", 66 | "@commitlint/config-conventional": "^7.1.2", 67 | "@types/jest": "^23.3.2", 68 | "@types/node": "^10.11.0", 69 | "@types/ramda": "^0.26.8", 70 | "@types/route-parser": "^0.1.2", 71 | "colors": "^1.3.2", 72 | "commitizen": "^3.0.0", 73 | "coveralls": "^3.0.2", 74 | "cross-env": "^5.2.0", 75 | "cz-conventional-changelog": "^2.1.0", 76 | "husky": "^1.0.1", 77 | "jest": "^23.6.0", 78 | "jest-config": "^23.6.0", 79 | "lint-staged": "^8.0.0", 80 | "lodash.camelcase": "^4.3.0", 81 | "prettier": "^1.14.3", 82 | "prompt": "^1.0.0", 83 | "replace-in-file": "^3.4.2", 84 | "rimraf": "^2.6.2", 85 | "rollup": "^0.67.0", 86 | "rollup-plugin-commonjs": "^9.1.8", 87 | "rollup-plugin-json": "^3.1.0", 88 | "rollup-plugin-node-resolve": "^3.4.0", 89 | "rollup-plugin-sourcemaps": "^0.4.2", 90 | "rollup-plugin-typescript2": "^0.25.3", 91 | "semantic-release": "^15.9.16", 92 | "shelljs": "^0.8.3", 93 | "travis-deploy-once": "^5.0.9", 94 | "ts-jest": "^23.10.2", 95 | "ts-node": "^7.0.1", 96 | "tslint": "^5.11.0", 97 | "tslint-config-prettier": "^1.15.0", 98 | "tslint-config-standard": "^8.0.1", 99 | "typedoc": "^0.12.0", 100 | "typescript": "^3.0.3" 101 | }, 102 | "dependencies": { 103 | "ajv": "^6.10.0", 104 | "ramda": "^0.26.1", 105 | "route-parser": "^0.0.5" 106 | }, 107 | "gitHead": "3ef5361da0254416cfdd89c6d9b2eeb2a8ea42a5" 108 | } 109 | -------------------------------------------------------------------------------- /packages/suppressor/rollup.config.ts: -------------------------------------------------------------------------------- 1 | import resolve from 'rollup-plugin-node-resolve' 2 | import commonjs from 'rollup-plugin-commonjs' 3 | import sourceMaps from 'rollup-plugin-sourcemaps' 4 | import camelCase from 'lodash.camelcase' 5 | import typescript from 'rollup-plugin-typescript2' 6 | import json from 'rollup-plugin-json' 7 | 8 | const pkg = require('./package.json') 9 | 10 | const libraryName = '@chaingun/suppressor' 11 | 12 | export default { 13 | input: `src/${libraryName}.ts`, 14 | output: [ 15 | { file: pkg.main, name: camelCase(libraryName), format: 'umd', sourcemap: true }, 16 | { file: pkg.module, format: 'es', sourcemap: true } 17 | ], 18 | // Indicate here external modules you don't wanna include in your bundle (i.e.: 'lodash') 19 | external: ['ramda', 'ajv', 'route-parser', 'route-parser/lib/route/visitors/regexp'], 20 | watch: { 21 | include: 'src/**' 22 | }, 23 | plugins: [ 24 | // Allow json resolution 25 | json(), 26 | // Compile TypeScript files 27 | typescript({ useTsconfigDeclarationDir: true }), 28 | // Allow bundling cjs modules (unlike webpack, rollup doesn't understand cjs) 29 | commonjs(), 30 | // Allow node_modules resolution, so you can use 'external' to control 31 | // which external modules to include in the bundle 32 | // https://github.com/rollup/rollup-plugin-node-resolve#usage 33 | resolve(), 34 | 35 | // Resolve source maps to the original source 36 | sourceMaps() 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /packages/suppressor/tools/gh-pages-publish.ts: -------------------------------------------------------------------------------- 1 | const { cd, exec, echo, touch } = require("shelljs") 2 | const { readFileSync } = require("fs") 3 | const url = require("url") 4 | 5 | let repoUrl 6 | let pkg = JSON.parse(readFileSync("package.json") as any) 7 | if (typeof pkg.repository === "object") { 8 | if (!pkg.repository.hasOwnProperty("url")) { 9 | throw new Error("URL does not exist in repository section") 10 | } 11 | repoUrl = pkg.repository.url 12 | } else { 13 | repoUrl = pkg.repository 14 | } 15 | 16 | let parsedUrl = url.parse(repoUrl) 17 | let repository = (parsedUrl.host || "") + (parsedUrl.path || "") 18 | let ghToken = process.env.GH_TOKEN 19 | 20 | echo("Deploying docs!!!") 21 | cd("docs") 22 | touch(".nojekyll") 23 | exec("git init") 24 | exec("git add .") 25 | exec('git config user.name "go1dfish"') 26 | exec('git config user.email "me@go1dfish.me"') 27 | exec('git commit -m "docs(docs): update gh-pages"') 28 | exec( 29 | `git push --force --quiet "https://${ghToken}@${repository}" master:gh-pages` 30 | ) 31 | echo("Docs deployed!!") 32 | -------------------------------------------------------------------------------- /packages/suppressor/tools/semantic-release-prepare.ts: -------------------------------------------------------------------------------- 1 | const path = require("path") 2 | const { fork } = require("child_process") 3 | const colors = require("colors") 4 | 5 | const { readFileSync, writeFileSync } = require("fs") 6 | const pkg = JSON.parse( 7 | readFileSync(path.resolve(__dirname, "..", "package.json")) 8 | ) 9 | 10 | pkg.scripts.prepush = "npm run test:prod && npm run build" 11 | pkg.scripts.commitmsg = "commitlint -E HUSKY_GIT_PARAMS" 12 | 13 | writeFileSync( 14 | path.resolve(__dirname, "..", "package.json"), 15 | JSON.stringify(pkg, null, 2) 16 | ) 17 | 18 | // Call husky to set up the hooks 19 | fork(path.resolve(__dirname, "..", "node_modules", "husky", "lib", "installer", 'bin'), ['install']) 20 | 21 | console.log() 22 | console.log(colors.green("Done!!")) 23 | console.log() 24 | 25 | if (pkg.repository.url.trim()) { 26 | console.log(colors.cyan("Now run:")) 27 | console.log(colors.cyan(" npm install -g semantic-release-cli")) 28 | console.log(colors.cyan(" semantic-release-cli setup")) 29 | console.log() 30 | console.log( 31 | colors.cyan('Important! Answer NO to "Generate travis.yml" question') 32 | ) 33 | console.log() 34 | console.log( 35 | colors.gray( 36 | 'Note: Make sure "repository.url" in your package.json is correct before' 37 | ) 38 | ) 39 | } else { 40 | console.log( 41 | colors.red( 42 | 'First you need to set the "repository.url" property in package.json' 43 | ) 44 | ) 45 | console.log(colors.cyan("Then run:")) 46 | console.log(colors.cyan(" npm install -g semantic-release-cli")) 47 | console.log(colors.cyan(" semantic-release-cli setup")) 48 | console.log() 49 | console.log( 50 | colors.cyan('Important! Answer NO to "Generate travis.yml" question') 51 | ) 52 | } 53 | 54 | console.log() 55 | -------------------------------------------------------------------------------- /packages/suppressor/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { "*": ["types/*"] }, 5 | "moduleResolution": "node", 6 | "target": "es5", 7 | "module": "es2015", 8 | "lib": ["es2015", "es2016", "es2017", "dom"], 9 | "strict": true, 10 | "sourceMap": true, 11 | "declaration": true, 12 | "allowSyntheticDefaultImports": true, 13 | "experimentalDecorators": true, 14 | "emitDecoratorMetadata": true, 15 | "declarationDir": "dist/types", 16 | "outDir": "dist/lib", 17 | "typeRoots": ["node_modules/@types"] 18 | }, 19 | "include": ["src"] 20 | } 21 | -------------------------------------------------------------------------------- /packages/suppressor/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "tslint-config-standard", 4 | "tslint-config-prettier" 5 | ] 6 | } -------------------------------------------------------------------------------- /packages/suppressor/types/route-parser.d.ts: -------------------------------------------------------------------------------- 1 | export = index; 2 | declare class index { 3 | constructor(spec: any); 4 | match(path: any): any; 5 | reverse(params: any): any; 6 | } 7 | -------------------------------------------------------------------------------- /packages/types/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | max_line_length = 80 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | max_line_length = 0 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /packages/types/.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Example Contributing Guidelines 2 | 3 | This is an example of GitHub's contributing guidelines file. Check out GitHub's [CONTRIBUTING.md help center article](https://help.github.com/articles/setting-guidelines-for-repository-contributors/) for more information. 4 | -------------------------------------------------------------------------------- /packages/types/.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **I'm submitting a ...** 2 | [ ] bug report 3 | [ ] feature request 4 | [ ] question about the decisions made in the repository 5 | [ ] question about how to use this project 6 | 7 | * **Summary** 8 | 9 | 10 | 11 | * **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.) 12 | -------------------------------------------------------------------------------- /packages/types/.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...) 2 | 3 | 4 | 5 | * **What is the current behavior?** (You can also link to an open issue here) 6 | 7 | 8 | 9 | * **What is the new behavior (if this is a feature change)?** 10 | 11 | 12 | 13 | * **Other information**: 14 | -------------------------------------------------------------------------------- /packages/types/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | test 4 | src/**.js 5 | .idea/* 6 | 7 | coverage 8 | .nyc_output 9 | *.log 10 | 11 | package-lock.json -------------------------------------------------------------------------------- /packages/types/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | tsconfig.json 4 | tsconfig.module.json 5 | tslint.json 6 | .travis.yml 7 | .github 8 | .prettierignore 9 | .vscode 10 | build/docs 11 | **/*.spec.* 12 | coverage 13 | .nyc_output 14 | *.log 15 | -------------------------------------------------------------------------------- /packages/types/.prettierignore: -------------------------------------------------------------------------------- 1 | # package.json is formatted by package managers, so we ignore it here 2 | package.json -------------------------------------------------------------------------------- /packages/types/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | ### [0.18.1](https://github.com/chain-gun/types/compare/v0.17.0...v0.18.1) (2020-01-24) 6 | 7 | 8 | 9 | ### [0.17.1](https://github.com/chain-gun/types/compare/v0.16.0...v0.17.1) (2020-01-24) 10 | 11 | 12 | 13 | ### [0.16.1](https://github.com/chain-gun/types/compare/v0.15.1...v0.16.1) (2020-01-24) 14 | 15 | 16 | 17 | ### 0.13.1 (2020-01-24) 18 | -------------------------------------------------------------------------------- /packages/types/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 go1dfish 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/types/README.md: -------------------------------------------------------------------------------- 1 | # @chaingun/types 2 | 3 | ChainGun shared types 4 | -------------------------------------------------------------------------------- /packages/types/src/ChainGun.ts: -------------------------------------------------------------------------------- 1 | import { GunGraphData, GunMsg } from '.' 2 | 3 | export type GunMsgCb = (msg: GunMsg) => void 4 | 5 | /** 6 | * How puts are communicated to ChainGun connectors 7 | */ 8 | export interface ChainGunPut { 9 | readonly graph: GunGraphData 10 | readonly msgId?: string 11 | readonly replyTo?: string 12 | readonly cb?: GunMsgCb 13 | } 14 | 15 | /** 16 | * How gets are communicated to ChainGun connectors 17 | */ 18 | export interface ChainGunGet { 19 | readonly soul: string 20 | readonly msgId?: string 21 | readonly key?: string 22 | readonly cb?: GunMsgCb 23 | } 24 | -------------------------------------------------------------------------------- /packages/types/src/Gun.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Timestamp of last change for each attribute 3 | */ 4 | export interface GunNodeState { 5 | readonly [key: string]: number 6 | } 7 | 8 | /** 9 | * Soul and State of a Gun Node 10 | */ 11 | export interface GunNodeMeta { 12 | readonly '#': string 13 | readonly '>': GunNodeState 14 | } 15 | 16 | /** 17 | * A node (or partial node data) in a Gun Graph 18 | */ 19 | export interface GunNode { 20 | readonly _: GunNodeMeta 21 | // tslint:disable-next-line: no-mixed-interface 22 | readonly [key: string]: any 23 | } 24 | 25 | /** 26 | * Gun Graph Data consists of one or more full or partial nodes 27 | */ 28 | export interface GunGraphData { 29 | readonly [key: string]: GunNode | undefined 30 | } 31 | 32 | /** 33 | * A standard Gun Protocol Message 34 | */ 35 | export interface GunMsg { 36 | readonly '#'?: string 37 | readonly '@'?: string 38 | 39 | readonly get?: { 40 | readonly '#': string 41 | } 42 | 43 | readonly put?: GunGraphData 44 | 45 | readonly ack?: number | boolean 46 | readonly err?: any 47 | readonly ok?: boolean | number 48 | } 49 | 50 | /** 51 | * Valid values in GunDB 52 | */ 53 | export type GunValue = object | string | number | boolean | null 54 | -------------------------------------------------------------------------------- /packages/types/src/GunGraphAdapter.ts: -------------------------------------------------------------------------------- 1 | import { GunGraphData, GunNode } from './Gun' 2 | 3 | export type ChangeSetEntry = readonly [string, GunGraphData] 4 | 5 | export interface GunGetOpts { 6 | readonly '.'?: string 7 | readonly '>'?: string 8 | readonly '<'?: string 9 | readonly '%'?: string 10 | } 11 | 12 | export interface GunGraphAdapter { 13 | readonly close?: () => void 14 | readonly get: (soul: string, opts?: GunGetOpts) => Promise 15 | readonly getJsonString?: (soul: string, opts?: GunGetOpts) => Promise 16 | readonly getJsonStringSync?: (soul: string, opts?: GunGetOpts) => string 17 | readonly getSync?: (soul: string, opts?: GunGetOpts) => GunNode | null 18 | readonly put: (graphData: GunGraphData) => Promise 19 | readonly putSync?: (graphData: GunGraphData) => GunGraphData | null 20 | 21 | readonly pruneChangelog?: (before: number) => Promise 22 | 23 | readonly getChangesetFeed?: ( 24 | from: string 25 | ) => () => Promise 26 | 27 | readonly onChange?: ( 28 | handler: (change: ChangeSetEntry) => void, 29 | from?: string 30 | ) => () => void 31 | } 32 | -------------------------------------------------------------------------------- /packages/types/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Gun' 2 | export * from './ChainGun' 3 | export * from './GunGraphAdapter' 4 | -------------------------------------------------------------------------------- /packages/types/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "outDir": "build/main", 5 | "rootDir": "src", 6 | "moduleResolution": "node", 7 | "module": "commonjs", 8 | "declaration": true, 9 | "inlineSourceMap": true, 10 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, 11 | 12 | "strict": true /* Enable all strict type-checking options. */, 13 | 14 | /* Strict Type-Checking Options */ 15 | // "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, 16 | // "strictNullChecks": true /* Enable strict null checks. */, 17 | // "strictFunctionTypes": true /* Enable strict checking of function types. */, 18 | // "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */, 19 | // "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, 20 | // "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, 21 | 22 | /* Additional Checks */ 23 | "noUnusedLocals": true /* Report errors on unused locals. */, 24 | "noUnusedParameters": true /* Report errors on unused parameters. */, 25 | "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, 26 | "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, 27 | 28 | /* Debugging Options */ 29 | "traceResolution": false /* Report module resolution log messages. */, 30 | "listEmittedFiles": false /* Print names of generated files part of the compilation. */, 31 | "listFiles": false /* Print names of files part of the compilation. */, 32 | "pretty": true /* Stylize errors and messages using color and context. */, 33 | 34 | /* Experimental Options */ 35 | // "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, 36 | // "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, 37 | 38 | "lib": ["es2017"], 39 | "types": [], 40 | "typeRoots": ["node_modules/@types", "src/types"] 41 | }, 42 | "include": ["src/**/*.ts"], 43 | "exclude": ["node_modules/**"], 44 | "compileOnSave": false 45 | } 46 | -------------------------------------------------------------------------------- /packages/types/tsconfig.module.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "outDir": "build/module", 6 | "module": "esnext" 7 | }, 8 | "exclude": [ 9 | "node_modules/**" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /packages/types/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["tslint:latest", "tslint-config-prettier", "tslint-immutable"], 3 | "rules": { 4 | "interface-name": [true, "never-prefix"], 5 | // TODO: allow devDependencies only in **/*.spec.ts files: 6 | // waiting on https://github.com/palantir/tslint/pull/3708 7 | "no-implicit-dependencies": [true, "dev"], 8 | 9 | /* tslint-immutable rules */ 10 | // Recommended built-in rules 11 | "no-var-keyword": true, 12 | "no-parameter-reassignment": true, 13 | "typedef": [true, "call-signature"], 14 | 15 | // Immutability rules 16 | "readonly-keyword": true, 17 | "readonly-array": true, 18 | "no-let": true, 19 | "no-object-mutation": true, 20 | "no-delete": true, 21 | "no-method-signature": true, 22 | 23 | // Functional style rules 24 | "no-this": true, 25 | "no-class": true, 26 | "no-mixed-interface": true, 27 | "no-expression-statement": [ 28 | true, 29 | { "ignore-prefix": ["console.", "process.exit"] } 30 | ], 31 | "no-if-statement": true 32 | /* end tslint-immutable rules */ 33 | } 34 | } 35 | --------------------------------------------------------------------------------