Skip to content
This repository has been archived by the owner on Sep 14, 2023. It is now read-only.

Commit

Permalink
feat: rune (#454)
Browse files Browse the repository at this point in the history
Co-authored-by: Harry Solovay <[email protected]>
  • Loading branch information
tjjfvi and harrysolovay authored Feb 8, 2023
1 parent 1c50936 commit 3fbb532
Show file tree
Hide file tree
Showing 161 changed files with 4,341 additions and 2,775 deletions.
3 changes: 1 addition & 2 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,5 @@
"streetsidesoftware.code-spell-checker",
"vadimcn.vscode-lldb",
"bungcip.better-toml"
],
"postCreateCommand": "deno task star"
]
}
17 changes: 17 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Lint
on:
pull_request:
push:
branches:
- main
jobs:
star:
name: Lint
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v3
- uses: denoland/setup-deno@9db7f66e8e16b5699a514448ce994936c63f0d54 # v1.1.0
with:
deno-version: v1.x
- run: deno lint
42 changes: 42 additions & 0 deletions .github/workflows/star.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Star
on:
pull_request:
push:
branches:
- main
jobs:
star:
name: Star
runs-on: ubuntu-latest
timeout-minutes: 30 # :(
steps:
- uses: actions/checkout@v3
- uses: denoland/setup-deno@9db7f66e8e16b5699a514448ce994936c63f0d54 # v1.1.0
with:
deno-version: v1.x
- name: Cache Deno dependencies
uses: actions/cache@v3
with:
path: |
~/.deno
~/.cache/deno
key: ${{ runner.os }}-deno-${{ hashFiles('deps/**/*.ts') }}
- name: Setup Polkadot
uses: ./.github/actions/setup-binary
with:
binary-name: polkadot
binary-version: v0.9.36
binary-github: https://github.com/paritytech/polkadot
- name: Setup Cumulus
uses: ./.github/actions/setup-binary
with:
binary-name: polkadot-parachain
binary-version: v0.9.370
binary-github: https://github.com/paritytech/cumulus
- name: Setup Zombienet
uses: ./.github/actions/setup-binary
with:
binary-name: zombienet-linux
binary-version: v1.3.18
binary-github: https://github.com/paritytech/zombienet
- run: deno task star
4 changes: 1 addition & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,13 @@ jobs:
uses: ./.github/actions/setup-binary
with:
binary-name: polkadot-parachain
binary-version: v0.9.360
binary-version: v0.9.370
binary-github: https://github.com/paritytech/cumulus
- name: Setup Zombienet
uses: ./.github/actions/setup-binary
with:
binary-name: zombienet-linux
binary-version: v1.3.18
binary-github: https://github.com/paritytech/zombienet
- run: deno lint
- run: deno task star
- run: deno task test
# - run: deno task test:examples
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
ARG VARIANT=bullseye
FROM --platform=linux/amd64 mcr.microsoft.com/devcontainers/base:0-${VARIANT} as vscode

ARG DENO_VERSION=1.30.0
ARG DENO_VERSION=1.30.3
ARG POLKADOT_VERSION=v0.9.36
ARG POLKADOT_PARACHAIN_VERSION=v0.9.360
ARG ZOMBIENET_VERSION=v1.3.30
Expand Down
2 changes: 1 addition & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> Capi is a work in progress. The documentation may not reflect the current implementation. **Expect a stable release and proper documentation in early 2023**.
Capi is a declarative, TypeScript-first toolkit for crafting interactions with Substrate-based chains. It consists of [FRAME](https://docs.substrate.io/reference/glossary/#frame) utilities and [a high-level functional effect system](https://github.com/paritytech/zones) and [effects](./effects), which facilitate multistep, multichain interactions without compromising either performance or safety.
Capi is a declarative, TypeScript-first toolkit for crafting interactions with Substrate-based chains. It consists of [FRAME](https://docs.substrate.io/reference/glossary/#frame) utilities and a high-level functional effect system (Rune) and fluent API, which facilitate multistep, multichain interactions without compromising either performance or safety.

- [Examples &rarr;](./examples)<br />SHOW ME THE CODE
- [API Reference &rarr;](https://deno.land/x/capi/mod.ts)<br />A generated API reference, based on type signatures and in-source comments.
Expand Down
4 changes: 0 additions & 4 deletions _tasks/dnt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ await Promise.all([
name: "scale-codec",
version: "^0.10.0",
},
"https://deno.land/x/[email protected]/mod.ts": {
name: "zones",
version: "0.1.0-beta.13",
},
"https://deno.land/x/[email protected]/index-deno.js": {
name: "@substrate/smoldot-light",
version: "0.7.6",
Expand Down
8 changes: 4 additions & 4 deletions _tasks/download_frame_metadata.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { rawClient as kusama } from "kusama/mod.ts"
import { rawClient as polkadot } from "polkadot/mod.ts"
import { rawClient as rococo } from "rococo/mod.ts"
import { rawClient as westend } from "westend/mod.ts"
import { rawClient as kusama } from "kusama/client.ts"
import { rawClient as polkadot } from "polkadot/client.ts"
import { rawClient as rococo } from "rococo/client.ts"
import { rawClient as westend } from "westend/client.ts"

const knownClients = { kusama, polkadot, westend, rococo }

Expand Down
69 changes: 68 additions & 1 deletion _tasks/star.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { parse } from "../deps/std/flags.ts"
import * as fs from "../deps/std/fs.ts"
import * as path from "../deps/std/path.ts"
import { getOrInit } from "../util/state.ts"

const { ignore } = parse(Deno.args, { string: ["ignore"] })
let generated = ""
Expand All @@ -16,5 +17,71 @@ for await (
const dir = path.join(Deno.cwd(), "target")
await fs.ensureDir(dir)
const dest = path.join(dir, "star.ts")
console.log(`Writing "${dest}".`)
await Deno.writeTextFile(dest, generated)

const data: Data = JSON.parse(
new TextDecoder().decode(
await Deno.run({ cmd: ["deno", "info", "--json", "target/star.ts"], stdout: "piped" }).output(),
),
)

interface Data {
redirects: Record<string, string>
modules: Array<{
specifier: string
dependencies?: Array<{
type?: {
specifier: string
}
code?: {
specifier: string
}
}>
}>
}

const dependencies = new Map<string, Set<string>>()

function visit(specifier: string) {
while (specifier in data.redirects) specifier = data.redirects[specifier]!
if (specifier.startsWith("npm:")) return new Set<string>()
return getOrInit(dependencies, specifier, () => {
const module = data.modules.find((x) => x.specifier === specifier)
if (!module) throw new Error("module not found " + specifier)
const set = new Set<string>([specifier])
dependencies.set(specifier, set)
for (const dep of module.dependencies ?? []) {
if (dep.code) {
for (const s of visit(dep.code.specifier)) {
set.add(s)
}
}
if (dep.type) {
for (const s of visit(dep.type.specifier)) {
set.add(s)
}
}
}
return set
})
}

for (const mod of data.modules) {
visit(mod.specifier)
}

const entries = [...dependencies.entries()].sort((a, b) => b[1].size - a[1].size)

const done = new Set()
for (const [file, deps] of entries.slice(1)) {
if (done.has(file)) continue
console.log(file)
const status = await Deno.run({ cmd: ["deno", "cache", "--check", file] })
.status()
if (!status.success) Deno.exit(status.code)
for (const d of deps) {
done.add(d)
}
}

console.log("Checked successfully")
5 changes: 0 additions & 5 deletions codegen/Codegen.ts

This file was deleted.

2 changes: 1 addition & 1 deletion codegen/File.ts → codegen/frame/File.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { tsFormatter } from "../deps/dprint.ts"
import { tsFormatter } from "../../deps/dprint.ts"

export class File {
constructor(public codeRaw = "") {}
Expand Down
82 changes: 82 additions & 0 deletions codegen/frame/FrameCodegen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { Metadata } from "../../frame_metadata/mod.ts"
import { SequenceTyDef, Ty } from "../../scale_info/mod.ts"
import { codecs } from "./codecs.ts"
import { File } from "./File.ts"
import { pallet } from "./pallet.ts"
import { type } from "./type.ts"
import { typeVisitor } from "./typeVisitor.ts"

export interface FrameCodegenProps {
metadata: Metadata
clientFile: File
}

export class FrameCodegen {
files = new Map<string, File>()

metadata
clientFile

typeVisitor
typeFiles = new Map<string, TypeFile>()

constructor({ metadata, clientFile }: FrameCodegenProps) {
this.metadata = metadata
this.clientFile = clientFile

this.typeVisitor = typeVisitor(this)

for (const [path, typeFile] of this.typeFiles) {
const filePath = path + typeFile.ext
this.files.set(filePath, type(this, path, filePath, typeFile))
}

this.files.set("codecs.ts", codecs(this))

this.files.set("client.ts", clientFile)

const callTy = Object
.fromEntries(this.metadata.extrinsic.ty.params.map((x) => [x.name.toLowerCase(), x.ty]))
.call!

const eventTy = (this.metadata
.pallets.find((x) => x.name === "System")
?.storage?.entries.find((x) => x.name === "Events")
?.value! as SequenceTyDef).typeParam

let palletNamespaceExports = ""
for (const p of this.metadata.pallets) {
if (!p.calls && !p.constants.length && !p.storage?.entries.length) continue
this.files.set(`${p.name}.ts`, pallet(this, p))
palletNamespaceExports += `export * as ${p.name} from "./${p.name}.ts"\n`
}

this.files.set(
"mod.ts",
new File(`
import * as C from "./capi.ts"
import * as types from "./types/mod.ts"
export type Chain = C.Chain<${this.typeVisitor.visit(callTy)}, ${
this.typeVisitor.visit(eventTy)
}>
export * from "./client.ts"
export * as types from "./types/mod.ts"
${palletNamespaceExports}
`),
)
}

[Symbol.iterator]() {
return Object.entries(this.files)[Symbol.iterator]()
}
}

export class TypeFile {
reexports = new Set<string>()
types = new Map<string, Ty>()
get ext() {
return this.reexports.size ? "/mod.ts" : ".ts"
}
}
6 changes: 3 additions & 3 deletions codegen/frame/codecs.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Ty, TyVisitor } from "../../scale_info/mod.ts"
import { normalizeIdent } from "../../util/case.ts"
import { File } from "../File.ts"
import { S } from "../util.ts"
import { FrameCodegen } from "./mod.ts"
import { File } from "./File.ts"
import { FrameCodegen } from "./FrameCodegen.ts"
import { S } from "./util.ts"

export function codecs(ctx: FrameCodegen) {
const { tys } = ctx.metadata
Expand Down
27 changes: 0 additions & 27 deletions codegen/frame/extrinsic.ts

This file was deleted.

Loading

0 comments on commit 3fbb532

Please sign in to comment.