Skip to content

Commit cf15028

Browse files
committed
merge docs/generator-slot
1 parent 54af90b commit cf15028

568 files changed

Lines changed: 61923 additions & 13104 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -10,41 +10,6 @@ on:
1010
- checks_requested
1111

1212
jobs:
13-
check-circular-deps:
14-
runs-on: ubuntu-latest
15-
steps:
16-
- uses: actions/checkout@v4
17-
18-
- name: Install pnpm
19-
uses: pnpm/action-setup@v4
20-
with:
21-
run_install: false
22-
23-
- name: Use Node.js
24-
uses: actions/setup-node@v4
25-
with:
26-
node-version: 22.x
27-
cache: 'pnpm'
28-
29-
- name: Install dpdm
30-
run: pnpm install -g dpdm
31-
32-
- name: Check circular dependencies
33-
run: dpdm --exit-code circular:1 packages/**/index.ts -T
34-
35-
lint-and-format:
36-
runs-on: ubuntu-latest
37-
steps:
38-
- uses: actions/checkout@v4
39-
- uses: biomejs/setup-biome@v2
40-
- uses: denoland/setup-deno@v2
41-
with:
42-
deno-version: v2.x # Run with latest stable Deno.
43-
- name: Lint
44-
run: biome ci --formatter-enabled=false --organize-imports-enabled=false .
45-
- name: Check formatting
46-
run: deno fmt --check
47-
4813
build-and-test:
4914
runs-on: ubuntu-latest
5015
steps:
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
name: Tree-shake test
2+
3+
on:
4+
pull_request:
5+
workflow_dispatch:
6+
inputs:
7+
target_branch:
8+
description: 'Target branch to compare against'
9+
required: true
10+
default: 'main'
11+
12+
jobs:
13+
treeshake-test:
14+
permissions:
15+
contents: read
16+
issues: write
17+
pull-requests: write
18+
runs-on: ubuntu-latest
19+
steps:
20+
- name: Install pnpm
21+
uses: pnpm/action-setup@v4
22+
with:
23+
version: 10.27.0
24+
run_install: false
25+
26+
- name: Checkout PR branch
27+
uses: actions/checkout@v4
28+
with:
29+
path: pr-branch
30+
31+
- name: Checkout target branch
32+
uses: actions/checkout@v4
33+
with:
34+
path: target-branch
35+
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.target_branch || github.base_ref }}
36+
37+
- name: Install dependencies (PR branch)
38+
working-directory: pr-branch
39+
run: pnpm install
40+
41+
- name: Install dependencies (target branch)
42+
working-directory: target-branch
43+
run: pnpm install
44+
45+
- name: Set up Node.js
46+
uses: actions/setup-node@v4
47+
with:
48+
node-version: 22.x
49+
cache: 'pnpm'
50+
cache-dependency-path: |
51+
pr-branch/pnpm-lock.yaml
52+
target-branch/pnpm-lock.yaml
53+
54+
- name: Generate import tests on PR branch
55+
working-directory: pr-branch
56+
run: pnpm --filter treeshake-test generate-tests
57+
58+
- name: Generate import tests on target branch
59+
working-directory: target-branch
60+
run: pnpm --filter treeshake-test generate-tests
61+
62+
- name: Run tree-shake test on PR branch
63+
working-directory: pr-branch
64+
run: pnpm --filter treeshake-test test --tsdown ${{ github.event_name == 'workflow_dispatch' && '--webpack' || '' }}
65+
66+
- name: Run tree-shake test on target branch
67+
working-directory: target-branch
68+
run: pnpm --filter treeshake-test test --tsdown ${{ github.event_name == 'workflow_dispatch' && '--webpack' || '' }}
69+
70+
- name: Compare results
71+
run: |
72+
node pr-branch/apps/treeshake-test/compareResults.ts \
73+
pr-branch/apps/treeshake-test/results.json \
74+
target-branch/apps/treeshake-test/results.json \
75+
> comparison.md
76+
77+
- name: Comment PR with results
78+
uses: actions/github-script@v7
79+
with:
80+
script: |
81+
const fs = require('fs');
82+
const comparison = fs.readFileSync('comparison.md', 'utf8');
83+
84+
const botCommentIdentifier = '<!-- treeshake-test-bot-comment -->';
85+
86+
async function findBotComment(issueNumber) {
87+
if (!issueNumber) return null;
88+
const comments = await github.rest.issues.listComments({
89+
owner: context.repo.owner,
90+
repo: context.repo.repo,
91+
issue_number: issueNumber,
92+
});
93+
return comments.data.find((comment) =>
94+
comment.body.includes(botCommentIdentifier)
95+
);
96+
}
97+
98+
async function createOrUpdateComment(issueNumber) {
99+
if (!issueNumber) {
100+
console.log('No issue number provided. Cannot post or update comment.');
101+
return;
102+
}
103+
104+
const existingComment = await findBotComment(issueNumber);
105+
if (existingComment) {
106+
await github.rest.issues.updateComment({
107+
...context.repo,
108+
comment_id: existingComment.id,
109+
body: botCommentIdentifier + '\n' + comparison,
110+
});
111+
} else {
112+
await github.rest.issues.createComment({
113+
...context.repo,
114+
issue_number: issueNumber,
115+
body: botCommentIdentifier + '\n' + comparison,
116+
});
117+
}
118+
}
119+
120+
const issueNumber = context.issue.number;
121+
if (!issueNumber) {
122+
console.log('No issue number found in context. Skipping comment.');
123+
} else {
124+
await createOrUpdateComment(issueNumber);
125+
}
126+
await core.summary
127+
.addRaw(comparison)
128+
.write();

README.md

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,41 @@
88

99
</div>
1010

11-
**TypeGPU** is a TypeScript library that enhances the WebGPU API, allowing
12-
resource management in a type-safe, declarative way.
11+
**TypeGPU** is a modular and open-ended toolkit for WebGPU, with advanced type
12+
inference and the ability to write shaders in TypeScript.
13+
14+
```ts
15+
const neighborhood = (a: number, r: number) => {
16+
'use gpu';
17+
return d.vec2f(a - r, a + r);
18+
};
19+
20+
//
21+
// #1) Can be called in JS
22+
//
23+
const range = neighborhood(1.1, 0.5);
24+
// ^? d.v2f
25+
26+
//
27+
// #2) Used to generate WGSL
28+
//
29+
const main = () => {
30+
'use gpu';
31+
return neighborhood(1.1, 0.5);
32+
};
33+
34+
const wgsl = tgpu.resolve([main]);
35+
// ^? string
36+
37+
//
38+
// #3) Executed on the GPU (generates WGSL underneath)
39+
//
40+
root['~unstable']
41+
.createGuardedComputePipeline(main)
42+
.dispatchThreads();
43+
```
1344

1445
<div align="center">
15-
<video width="512" autoplay muted loop playsinline src="https://github.com/user-attachments/assets/5bca716d-477d-44a1-a839-5df0c8d9044c"></video>
1646

1747
<!-- automd:badges color="plum" license name="typegpu" bundlephobia no-npmDownloads -->
1848

apps/bun-example/index.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ const createRandomBoid = tgpu.fn([], Boid)(() => {
1010
return { pos: randf.inUnitCube() };
1111
});
1212

13-
const shaderCode = tgpu.resolve({
14-
externals: { createRandomBoid },
15-
});
13+
const shaderCode = tgpu.resolve([createRandomBoid]);
1614

1715
console.log(shaderCode);

apps/treeshake-test/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
dist/
2+
3+
results.md
4+
results.json
5+
tests/*_from_*

apps/treeshake-test/bundleWith.ts

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import { build as esbuild } from 'esbuild';
2+
import * as fs from 'node:fs/promises';
3+
import * as path from 'node:path';
4+
import { build as tsdown } from 'tsdown';
5+
import esbuildPlugin from 'unplugin-typegpu/esbuild';
6+
import rolldownPlugin from 'unplugin-typegpu/rolldown';
7+
import webpackPlugin from 'unplugin-typegpu/webpack';
8+
import webpack from 'webpack';
9+
10+
export type ResultRecord = {
11+
testFilename: string;
12+
bundler: string;
13+
size: number;
14+
};
15+
16+
export async function bundleWithEsbuild(
17+
entryUrl: URL,
18+
outDir: URL,
19+
): Promise<URL> {
20+
const entryFileName = path.basename(entryUrl.pathname, '.ts');
21+
const outPath = new URL(`${entryFileName}.esbuild.js`, outDir);
22+
await esbuild({
23+
plugins: [esbuildPlugin({})],
24+
entryPoints: [entryUrl.pathname],
25+
bundle: true,
26+
outfile: outPath.pathname,
27+
format: 'esm',
28+
minify: true,
29+
treeShaking: true,
30+
});
31+
return outPath;
32+
}
33+
34+
export async function bundleWithWebpack(
35+
entryPath: URL,
36+
outDir: URL,
37+
): Promise<URL> {
38+
const entryFileName = path.basename(entryPath.pathname, '.ts');
39+
const outPath = new URL(`./${entryFileName}.webpack.js`, outDir);
40+
41+
return new Promise((resolve, reject) => {
42+
webpack(
43+
{
44+
entry: entryPath.pathname,
45+
output: {
46+
path: path.dirname(outPath.pathname),
47+
filename: path.basename(outPath.pathname),
48+
},
49+
plugins: [webpackPlugin({})],
50+
module: {
51+
rules: [
52+
{
53+
test: /\.ts$/,
54+
use: {
55+
loader: 'ts-loader',
56+
options: {
57+
compilerOptions: {
58+
module: 'es2015',
59+
target: 'es2015',
60+
esModuleInterop: true,
61+
allowSyntheticDefaultImports: true,
62+
skipLibCheck: true,
63+
},
64+
transpileOnly: true,
65+
},
66+
},
67+
exclude: /node_modules/,
68+
},
69+
],
70+
},
71+
optimization: {
72+
minimize: true,
73+
},
74+
},
75+
(err, stats) => {
76+
if (err || stats?.hasErrors()) {
77+
console.error(stats?.toString());
78+
reject(err || new Error('Webpack bundling failed'));
79+
} else {
80+
resolve(outPath);
81+
}
82+
},
83+
);
84+
});
85+
}
86+
87+
export async function bundleWithTsdown(
88+
entryUrl: URL,
89+
outDir: URL,
90+
): Promise<URL> {
91+
const entryFileName = path.basename(entryUrl.pathname, '.ts');
92+
const outPath = new URL(`./${entryFileName}.tsdown.js`, outDir);
93+
94+
try {
95+
await tsdown({
96+
plugins: [rolldownPlugin({})],
97+
outputOptions: {
98+
name: path.basename(outPath.pathname),
99+
dir: path.dirname(outPath.pathname),
100+
},
101+
minify: true,
102+
platform: 'neutral',
103+
clean: false,
104+
entry: {
105+
[`${entryFileName}.tsdown`]: entryUrl.pathname,
106+
},
107+
noExternal: /.*/,
108+
});
109+
110+
return outPath;
111+
} catch (error) {
112+
throw new Error(`tsdown bundling failed`, { cause: error });
113+
}
114+
}
115+
116+
export async function getFileSize(filePath: URL): Promise<number> {
117+
const stats = await fs.stat(filePath);
118+
return stats.size;
119+
}

0 commit comments

Comments
 (0)