@perspect3vism/ad4m
Advanced tools
Comparing version 0.0.6 to 0.1.0
{ | ||
"name": "@perspect3vism/ad4m", | ||
"version": "0.0.6", | ||
"version": "0.1.0", | ||
"description": "*The Agent-Centric Distributed Application Meta-ontology* or just: *Agent-Centric DApp Meta-ontology* * A new meta-ontology for interoperable, decentralized application design * A spanning-layer to enable seamless integration between Holochain DNAs, blockchains, linked-data structures/ontologies and centralized back-ends * The basis for turning distinct, monolithic and siloed apps into a global, open and interoperable sense-making network", | ||
"main": "index.js", | ||
"main": "lib/index.js", | ||
"types": "*.d.ts", | ||
"scripts": { | ||
"build": "tsc --declaration index.ts" | ||
"build": "tsc && npm run buildSchema", | ||
"buildSchema": "node lib/buildSchema.js", | ||
"test": "jest --forceExit" | ||
}, | ||
@@ -32,7 +34,19 @@ "repository": { | ||
"@types/jest": "^26.0.15", | ||
"@types/mocha": "^8.0.3" | ||
"@types/mocha": "^8.0.3", | ||
"class-validator": "^0.13.1", | ||
"graphql": "^15.5.0", | ||
"reflect-metadata": "^0.1.13", | ||
"type-graphql": "^1.1.1" | ||
}, | ||
"devDependencies": { | ||
"@apollo/client": "^3.3.20", | ||
"@apollo/link-error": "^2.0.0-beta.3", | ||
"@types/reflect-metadata": "^0.1.0", | ||
"apollo-server": "^2.25.2", | ||
"cross-fetch": "^3.1.4", | ||
"react": "^17.0.2", | ||
"ts-jest": "^27.0.3", | ||
"jest": "^27.0.4", | ||
"typescript": "^4.2.4" | ||
} | ||
} |
145
README.md
@@ -8,6 +8,134 @@ # AD4M | ||
* The basis for turning distinct, monolithic and siloed apps into a global, open and interoperable **sense-making network** | ||
--- | ||
## Overview | ||
## Ok, let's go... | ||
To build an app/UI against Ad4m, you need to make sure that an | ||
[ad4m-executor](https://github.com/perspect3vism/ad4m-executor) is running | ||
on the user's machine. | ||
Then use `Ad4mClient` to connect to and work with the running ad4m-executor like this: | ||
``` | ||
npm install --save @perspect3vism/ad4m | ||
``` | ||
In your code: | ||
```js | ||
import { Ad4mClient } from '@perspect3vism/ad4m' | ||
import { ApolloClient, ApolloLink, InMemoryCache } from "@apollo/client"; | ||
import { WebSocketLink } from '@apollo/client/link/ws'; | ||
import ws from "ws" | ||
const uri = 'http://localhost:4000/graphql' | ||
const apolloClient = new ApolloClient({ | ||
link: new WebSocketLink({ | ||
uri, | ||
options: { reconnect: true }, | ||
webSocketImpl: ws, | ||
}), | ||
cache: new InMemoryCache({resultCaching: false, addTypename: false}), | ||
defaultOptions: { | ||
watchQuery: { fetchPolicy: "no-cache" }, | ||
query: { fetchPolicy: "no-cache" } | ||
}, | ||
}); | ||
ad4mClient = new Ad4mClient(apolloClient) | ||
``` | ||
### Unlocking / initializing the agent | ||
You can't do much with the Ad4m runtime as long as the agent is not initialized. | ||
So first get the agent status to see if we either need to create new DID or unlock | ||
an existing keystore. | ||
```js | ||
const { isInitialized, isUnlocked, did } = await ad4mClient.agent.status() | ||
``` | ||
If `isInitialized` is `false` (and then `did` is empty) we need to create or import | ||
a DID and keys. `generate()` will create a new DID with method `key` and lock the | ||
keystore with the given passphrase. | ||
```js | ||
const { did } = await ad4mClient.agent.generate("passphrase") | ||
``` | ||
In following runs of the exectuor, `ad4mClient.agent.status()` will return a `did` | ||
and `isInitialized` true, but if `isUnlocked` is false, we need to unlock the keystore | ||
providing the passphrase: | ||
```js | ||
const { isUnlocked, did } = await ad4mClient.agent.unlock("passphrase") | ||
``` | ||
### Languages | ||
For creating an expression we need to select a language that we create an expression in: | ||
```js | ||
const languages = await ad4mClient.languages.all() | ||
const noteIpfsAddress = languages.find(l => l.name === 'note-ipfs').address | ||
``` | ||
### Creating an Expressions | ||
```js | ||
const exprAddress = await ad4mClient.expression.create("A new text note", noteIpfsAddress) | ||
``` | ||
### Creating a Perspective and linking that new Expression | ||
```js | ||
const perspectiveHandle = await ad4mClient.perspective.add("A new perspective on apps...") | ||
await ad4mClient.perspective.addLink( | ||
perspectiveHandle.uuid, | ||
new Link({ | ||
source: 'root', | ||
target: exprAddress | ||
}) | ||
) | ||
``` | ||
### Publishing that local Perspective by turning it into a Neighbourhood | ||
The back-bone of a Neighbourhood is a *LinkLanguage* - a Language that enables the sharing | ||
and thus synchronizing of links (see `LinksAdapter` in [Language.ts](src/language/Language.ts)). While there can and should be many different implementations | ||
with different trade-offs and features (like membranes etc.) the go-to implementation for now | ||
is *Social Context* from Junto: https://github.com/juntofoundation/Social-Context | ||
Let's assume we have downloaded the build files from their release directory, we can use it as | ||
a template to create a unique Language (with unique Holochain DNA in this case) like so: | ||
```js | ||
const uniqueLinkLanguage = await ad4mClient.languages.cloneHolochainTemplate(path.join(__dirname, "../languages/social-context"), "social-context", "b98e53a8-5800-47b6-adb9-86d55a74871e"); | ||
``` | ||
And then use this new LinkLanguage in our Neighbourhood: | ||
```js | ||
const meta = new Perspective() | ||
const neighbourhoodUrl = await ad4mClient.neighbourhood.publishFromPerspective( | ||
perspectiveHandle.uuid, | ||
uniqueLinkLanguage.address, | ||
meta | ||
) | ||
console.log(neighbourhoodUrl) // => neighbourhood://Qm123456789abcdef | ||
``` | ||
### Joining a Neighbourhood (on another node/agent) | ||
Assume everything above happened on Alice's agent. | ||
Alice now shares the Neighbourhood's URL with Bob. | ||
This is what Bob does to join the Neigbourhood, access it as a (local) Perspective | ||
and retrieve the Expression Alice created and linked there: | ||
```js | ||
const perspectiveHandle = await ad4mClient.neighbourhood.joinFromUrl(neighbourhoodUrl) | ||
const links = await ad4mClient.perspective.queryLinks(perspectiveHandle.uuid, {}) | ||
links.forEach(link => { | ||
const address = link.data.target | ||
const expression = await ad4mClient.expression.get(address) | ||
const data = JSON.parse(expression.data) | ||
console.log(data) //=> "A new text note" | ||
}) | ||
``` | ||
## Building from source | ||
Run: | ||
``` | ||
npm i && npm run build | ||
``` | ||
--- | ||
## Wait, what?! | ||
The central claim of AD4M is that any single- but also specifically multi-user application can be bootstrapped out of a meta-ontology consisting of 3 quintessential entities: | ||
@@ -40,3 +168,3 @@ * Agents | ||
* A Language of Languages, i.e. a way to talk about Languages so Languages can be created by users and shared. | ||
* A Language of Perspectives which implies the concept of **Shared Perspectives**, i.e. a way to share an otherwise local and private Perspective with others which constitutes the basic building block of any collaboration context. | ||
* A Language of Perspectives which implies the concept of **Shared Perspectives** a.k.a. **Neighbourhoods**, i.e. a way to share an otherwise local and private Perspective with others which constitutes the basic building block of any collaboration context. | ||
@@ -48,4 +176,4 @@ Having these Languages means Agents can author expressions that represent Agents, Languages and Perspectives. These expressions get linked from inside Perspectives. That way we can model primitives like friends-lists (Perspective including agent expressions), app-stores (Perspective including Languages) and more. | ||
Building an AD4M app actually means extending the AD4M ecosystem with the | ||
* Languages | ||
Building an AD4M app actually means extending the AD4M ecosystem with the | ||
* and link-ontologies | ||
@@ -56,10 +184,1 @@ | ||
The latter means creating RDF/semantic web style triplets that associate expressions in order to represent app specific semantics - not too different to how Solid style linked-data would work. | ||
### What can I do with AD4M now? | ||
There are 3 ways to use AD4M right now: | ||
1. Directly use [Perspect3ve](https://github.com/perspect3vism/perspect3ve) with its general purpose UI to manually create, link and share graphs of expressions of arbitrary type | ||
2. Just use the [AD4M executor](https://github.com/perspect3vism/ad4m-executor) which is the core engine and AD4M runtime used in Perspect3ve and connect your own UI via its [AD4M GraphQL interface](https://github.com/perspect3vism/ad4m-executor/blob/main/src/core/graphQL-interface/GraphQL.ts) but run the exact same code for driving Agents, Languages and Perspectives | ||
3. Just understand the paradigm shift to a complete agent-centric meta-ontology that AD4M represents und apply it to your otherwise unrelated code base. Making your code interoperable with other AD4M implementations will be possible just by wrapping Languages |
@@ -7,3 +7,4 @@ { | ||
// "incremental": true, /* Enable incremental compilation */ | ||
"target": "es2017", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ | ||
"target": "es2018", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ | ||
"lib": ["es2018", "esnext.asynciterable"], | ||
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ | ||
@@ -14,7 +15,8 @@ // "lib": [], /* Specify library files to be included in the compilation. */ | ||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ | ||
// "declaration": true, /* Generates corresponding '.d.ts' file. */ | ||
"declaration": true, /* Generates corresponding '.d.ts' file. */ | ||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ | ||
// "sourceMap": true, /* Generates corresponding '.map' file. */ | ||
// "outFile": "./", /* Concatenate and emit output to single file. */ | ||
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ | ||
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ | ||
"outDir": "./lib", | ||
// "composite": true, /* Enable project compilation */ | ||
@@ -70,4 +72,7 @@ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ | ||
"skipLibCheck": true, /* Skip type checking of declaration files. */ | ||
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ | ||
} | ||
"forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */ | ||
"emitDecoratorMetadata": true, | ||
"experimentalDecorators": true, | ||
"allowSyntheticDefaultImports": true | ||
}, | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
88934
1933
181
0
7
9
42
1
+ Addedclass-validator@^0.13.1
+ Addedgraphql@^15.5.0
+ Addedreflect-metadata@^0.1.13
+ Addedtype-graphql@^1.1.1
+ Added@types/glob@7.2.0(transitive)
+ Added@types/minimatch@5.1.2(transitive)
+ Added@types/node@22.10.1(transitive)
+ Added@types/semver@7.5.8(transitive)
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbrace-expansion@1.1.11(transitive)
+ Addedclass-validator@0.13.2(transitive)
+ Addedconcat-map@0.0.1(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedglob@7.2.3(transitive)
+ Addedgraphql@15.9.0(transitive)
+ Addedgraphql-query-complexity@0.7.2(transitive)
+ Addedgraphql-subscriptions@1.2.1(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addediterall@1.3.0(transitive)
+ Addedlibphonenumber-js@1.11.15(transitive)
+ Addedlodash.get@4.4.2(transitive)
+ Addedminimatch@3.1.2(transitive)
+ Addednanoid@3.3.8(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedreflect-metadata@0.1.14(transitive)
+ Addedsemver@7.6.3(transitive)
+ Addedtslib@2.8.1(transitive)
+ Addedtype-graphql@1.1.1(transitive)
+ Addedundici-types@6.20.0(transitive)
+ Addedvalidator@13.12.0(transitive)
+ Addedwrappy@1.0.2(transitive)
- Removed@types/node@22.9.4(transitive)
- Removednanoid@3.3.7(transitive)
- Removedundici-types@6.19.8(transitive)