use internal ts package
ci / build (push) Waiting to run Details

This commit is contained in:
CJ_Clippy 2024-07-19 00:01:06 -08:00
parent a7b6439418
commit 3aa6081b8a
27 changed files with 3265 additions and 156 deletions

View File

@ -1,34 +0,0 @@
## boop is an example package showing how to include dependency workspace packages into the docker build
FROM node:20.15 as base
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
WORKDIR /usr/src/app
RUN corepack enable && corepack prepare pnpm@9.2.0 --activate
FROM base as build
# ENV NODE_ENV=development
# RUN mkdir -p /usr/src/app/packages/boop && mkdir /usr/src/app/packages/taco && mkdir -p /prod/boop
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc .
COPY ./packages/boop/pnpm-lock.yaml ./packages/boop/package.json ./packages/boop/
COPY ./packages/taco/pnpm-lock.yaml ./packages/taco/package.json ./packages/taco/
COPY ./packages/types/pnpm-lock.yaml ./packages/types/package.json ./packages/types/
# RUN pnpm fetch
# I think pnpm install is broken.
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile --offline
COPY ./packages/boop/ ./packages/boop/
COPY ./packages/taco/ ./packages/taco/
COPY ./packages/types/ ./packages/types/
RUN echo "@@@@@@@@@@@@@@@@@@@@ show me the meat!"
RUN ls -lash ./
RUN ls -lash ./packages/boop
RUN pnpm -r build
RUN pnpm deploy --filter=boop --prod /prod/boop
FROM base as boop
WORKDIR /app
ENV NODE_ENV=production
COPY --from=build /prod/boop .
RUN ls -la .
ENTRYPOINT ["pnpm", "start"]

29
d.meal.dockerfile Normal file
View File

@ -0,0 +1,29 @@
## meal is an example package showing how to include dependency workspace packages into the docker build
FROM node:20.15 AS base
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
WORKDIR /app
RUN corepack enable && corepack prepare pnpm@9.5.0 --activate
FROM base AS build
# ENV NODE_ENV=development
# RUN mkdir -p /app/packages/meal && mkdir /app/packages/taco && mkdir -p /prod/meal
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc .
COPY ./packages/meal/pnpm-lock.yaml ./packages/meal/package.json ./packages/meal/
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm fetch
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile --offline
COPY ./packages/meal/ ./packages/meal/
RUN echo "@@@@@@@@@@@@@@@@@@@@ show me the meat!"
RUN ls -lash ./
RUN ls -lash ./packages/meal
RUN pnpm -r build
RUN pnpm deploy --filter=meal --prod /prod/meal
FROM base AS meal
WORKDIR /app
ENV NODE_ENV=production
COPY --from=build /prod/meal .
RUN ls -la .
ENTRYPOINT ["pnpm", "start"]

View File

@ -26,7 +26,7 @@ FROM node:20 AS base
ENV PNPM_HOME="/pnpm" ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH" ENV PATH="$PNPM_HOME:$PATH"
WORKDIR /app WORKDIR /app
RUN corepack enable && corepack prepare pnpm@9.2.0 --activate RUN corepack enable && corepack prepare pnpm@9.5.0 --activate
FROM base AS build FROM base AS build
WORKDIR /app WORKDIR /app
@ -56,16 +56,17 @@ COPY ./packages/types/ ./packages/types/
COPY ./packages/utils/ ./packages/utils/ COPY ./packages/utils/ ./packages/utils/
## Transpile TS into JS ## Transpile TS into JS
## we have to build @futureporn/image first because other packages depend on it's build js files ## we have to build @futureporn/image first because other packages depend on it's built js files
## next we have to build temporal-workflows because other packages depend on it's built js files ## next we build everything else
RUN pnpm --filter=@futureporn/image build RUN pnpm --filter=@futureporn/image build
RUN pnpm --filter=@futureporn/temporal-workflows build RUN pnpm --filter=!@futureporn/image -r build
RUN pnpm --filter=!@futureporn/temporal-workflows -r build
## Deploy (copy all production code into one place) ## Copy all production code into one place
## `pnpm deploy` copies all dependencies into an isolated node_modules directory inside the target dir
## @see https://pnpm.io/cli/deploy
RUN pnpm deploy --filter=@futureporn/temporal-worker --prod /prod/temporal-worker RUN pnpm deploy --filter=@futureporn/temporal-worker --prod /prod/temporal-worker
RUN ls -lash /prod/temporal-worker RUN echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ here"
# RUN ls -lash /prod/temporal-worker/
FROM base AS worker FROM base AS worker
COPY --from=build /prod/temporal-worker . COPY --from=build /prod/temporal-worker .

View File

@ -1,18 +0,0 @@
import { bell } from '@futureporn/taco'
import { IPagination } from '@futureporn/types'
function main() {
const page: IPagination = {
page: 5,
pageCount: 20,
pageSize: 50,
total: 365
}
console.log(bell()+' page:'+page.page)
setTimeout(() => {
return main()
}, 2000)
}
main()

View File

@ -1,31 +0,0 @@
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
dependencies:
'@futureporn/taco':
specifier: workspace:*
version: link:../taco
'@futureporn/types':
specifier: workspace:*
version: link:../types
devDependencies:
typescript:
specifier: ^5.5.3
version: 5.5.3
packages:
typescript@5.5.3:
resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==}
engines: {node: '>=14.17'}
hasBin: true
snapshots:
typescript@5.5.3: {}

7
packages/meal/README.md Normal file
View File

@ -0,0 +1,7 @@
# @futureporn/meal
A test package to better understand Internal TypeScript Packages [[1](https://github.com/0x80/isolate-package?tab=readme-ov-file#the-internal-packages-strategy)] [[2](https://turbo.build/blog/you-might-not-need-typescript-project-references)] [[3](https://www.typescriptlang.org/docs/handbook/project-references.html)]
The TL;DR: The consuming application of an internal package must transpile and typecheck it.
In this example, @futureporn/meal consumes @futureporn/taco. A build step happens only in @futureporn/meal.

View File

@ -1,24 +1,28 @@
{ {
"name": "@futureporn/boop", "name": "@futureporn/meal",
"type": "module", "type": "module",
"version": "1.0.1", "version": "1.0.1",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"private": true,
"scripts": { "scripts": {
"test": "echo \"Warn: no test specified\" && exit 0", "test": "echo \"Warn: no test specified\" && exit 0",
"start": "node dist/index.js", "start": "node dist/index.js",
"build": "tsc --build", "build": "tsc --build",
"clean": "rm -rf dist", "clean": "rm -rf dist",
"superclean": "rm -rf node_modules && rm -rf pnpm-lock.yaml && rm -rf dist" "superclean": "rm -rf node_modules && rm -rf pnpm-lock.yaml && rm -rf dist",
"dev": "tsup ./src/index.ts --watch"
}, },
"dependencies": { "dependencies": {
"@futureporn/taco": "workspace:*", "@futureporn/taco": "workspace:*",
"@futureporn/types": "workspace:*" "@futureporn/types": "workspace:*"
}, },
"keywords": [], "keywords": [],
"author": "", "author": "@CJ_Clippy",
"license": "Unlicense", "license": "Unlicense",
"devDependencies": { "devDependencies": {
"@types/node": "^20.14.9",
"tsup": "^8.1.2",
"typescript": "^5.5.3" "typescript": "^5.5.3"
} }
} }

1315
packages/meal/pnpm-lock.yaml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
import { type Taco, taco } from '@futureporn/taco'
function main() {
console.log(`Oh boy, it's time for another delicious ${taco()}!!`)
setTimeout(() => {
return main()
}, 2000)
}
main()

View File

@ -22,10 +22,10 @@
}, },
// Include the necessary files for your project // Include the necessary files for your project
"include": [ "include": [
"**/*.ts", "**/*.ts"
"**/*.tsx"
], ],
"exclude": [ "exclude": [
"node_modules" "node_modules",
"tsub.config.ts"
] ]
} }

View File

@ -0,0 +1,23 @@
import { defineConfig } from "tsup";
import { exec } from 'child_process';
export default defineConfig({
entry: ["src/index.ts"],
format: ["esm"],
target: "node20",
clean: true,
sourcemap: true,
/**
* The common package is using the internal packages approach, so it needs to
* be transpiled / bundled together with the deployed code.
*/
noExternal: ["@futureporn/taco"],
/**
* We do not use tsup for generating d.ts files because it can not generate type
* the definition maps required for go-to-definition to work in our IDE. We
* use tsc for that.
*/
onSuccess: async () => {
exec('tsc --emitDeclarationOnly');
},
});

View File

@ -9,7 +9,7 @@
}, },
"scripts": { "scripts": {
"test": "mocha --require ts-node/register src/**/*.spec.ts", "test": "mocha --require ts-node/register src/**/*.spec.ts",
"build": "tsc --build", "build": "tsup",
"dev": "nodemon --ext js,ts,json,yaml --exec \"node --loader ts-node/esm --disable-warning=ExperimentalWarning ./src/index.ts\"", "dev": "nodemon --ext js,ts,json,yaml --exec \"node --loader ts-node/esm --disable-warning=ExperimentalWarning ./src/index.ts\"",
"start": "node ./dist/index.js", "start": "node ./dist/index.js",
"clean": "rm -rf dist", "clean": "rm -rf dist",
@ -59,6 +59,7 @@
"mocha": "^10.4.0", "mocha": "^10.4.0",
"nodemon": "^3.1.4", "nodemon": "^3.1.4",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"tsup": "^8.1.2",
"typescript": "^5.5.3" "typescript": "^5.5.3"
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,7 @@ import { Client, Connection } from '@temporalio/client'
// import { type NotificationData } from '@futureporn/types' // import { type NotificationData } from '@futureporn/types'
// import { type FetchMessageObject } from 'imapflow' // import { type FetchMessageObject } from 'imapflow'
import { createId } from '@paralleldrive/cuid2' import { createId } from '@paralleldrive/cuid2'
import { WorkflowA } from '@futureporn/temporal-workflows/workflows.js' import { WorkflowA } from '@futureporn/temporal-workflows/workflows'
console.log('connecting to temporal...') console.log('connecting to temporal...')
const connection = await Connection.connect({ address: 'temporal-frontend.futureporn.svc.cluster.local:7233' }); const connection = await Connection.connect({ address: 'temporal-frontend.futureporn.svc.cluster.local:7233' });

View File

@ -0,0 +1,23 @@
import { defineConfig } from "tsup";
import { exec } from 'child_process';
export default defineConfig({
entry: ["src/index.ts"],
format: ["esm"],
target: "node20",
clean: true,
sourcemap: true,
/**
* The common package is using the internal packages approach, so it needs to
* be transpiled / bundled together with the deployed code.
*/
noExternal: ["@futureporn/temporal-workflows"],
/**
* We do not use tsup for generating d.ts files because it can not generate type
* the definition maps required for go-to-definition to work in our IDE. We
* use tsc for that.
*/
onSuccess: async () => {
exec('tsc --emitDeclarationOnly');
},
});

8
packages/taco/README.md Normal file
View File

@ -0,0 +1,8 @@
# @futureporn/taco
A test package to better understand Internal TypeScript Packages [[1](https://github.com/0x80/isolate-package?tab=readme-ov-file#the-internal-packages-strategy)] [[2](https://turbo.build/blog/you-might-not-need-typescript-project-references)] [[3](https://www.typescriptlang.org/docs/handbook/project-references.html)]
The TL;DR: The consuming application of an internal package must transpile and typecheck it.
In this example, @futureporn/meal consumes @futureporn/taco. A build step happens only in @futureporn/meal.

View File

@ -1,5 +0,0 @@
export function bell() {
return "DING DONG DING DING DONG ITS TIME TO EAT A TACO ITS TUESDAY MY DUDE!~"
}

View File

@ -3,11 +3,12 @@
"type": "module", "type": "module",
"version": "1.0.0", "version": "1.0.0",
"description": "", "description": "",
"main": "index.js", "main": "./src/index.ts",
"types": "./src/index.ts",
"scripts": { "scripts": {
"test": "echo \"Warn: no test specified\" && exit 0" "test": "echo \"Warn: no test specified\" && exit 0"
}, },
"keywords": [], "keywords": [],
"author": "", "author": "@CJ_Clippy",
"license": "ISC" "license": "Unlicense"
} }

View File

@ -0,0 +1,19 @@
export type Taco = {
meat: Boolean;
cheese: Boolean;
lettuce: Boolean;
salsa: Boolean;
crunchy: Boolean;
}
export function taco(): Taco {
return {
meat: true,
cheese: false,
lettuce: true,
salsa: true,
crunchy: true
}
}

View File

View File

@ -1,3 +1,15 @@
# temporal-worker # @futureporn/temporal-worker
The system component which runs background tasks such as thumbnail generation, video encoding, file transfers, etc.
We use [Temporal](https://temporal.io/) for running "durable tasks".
This code gets built into commonjs by tsup because of some [Temporal wierdness](https://community.temporal.io/t/start-temporal-worker-in-webpack-project/11785) relating to how imports workflows.
### Temporal's monorepo reference
@see https://github.com/temporalio/samples-typescript/tree/main/monorepo-folders
@see https://github.com/temporalio/samples-typescript/tree/main/monorepo-folders

View File

@ -7,11 +7,11 @@
"dist" "dist"
], ],
"scripts": { "scripts": {
"build": "tsc --build", "build": "tsup --sourcemap inline",
"isolate": "npx isolate-package isolate", "isolate": "npx isolate-package isolate",
"lint": "eslint .", "lint": "eslint .",
"dev": "nodemon --ext js,ts,json,yaml --watch ./worker.ts --watch ../temporal-workflows --exec \"node --loader ts-node/esm --disable-warning=ExperimentalWarning ./worker.ts\"", "dev": "nodemon --ext js,ts,json,yaml --watch ./worker.ts --watch ../temporal-workflows --exec \"node --loader ts-node/esm --disable-warning=ExperimentalWarning ./worker.ts\"",
"start": "node dist/temporal-worker/src/worker.js", "start": "node dist/index.cjs",
"clean": "rm -rf dist", "clean": "rm -rf dist",
"superclean": "rm -rf node_modules && rm -rf pnpm-lock.yaml && rm -rf dist" "superclean": "rm -rf node_modules && rm -rf pnpm-lock.yaml && rm -rf dist"
}, },
@ -31,9 +31,11 @@
}, },
"packageManager": "pnpm@9.5.0", "packageManager": "pnpm@9.5.0",
"devDependencies": { "devDependencies": {
"@types/node": "^20.14.9",
"isolate-package": "^1.19.0", "isolate-package": "^1.19.0",
"nodemon": "^2.0.15", "nodemon": "^2.0.15",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"tsup": "^8.1.2",
"typescript": "^5.5.3" "typescript": "^5.5.3"
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,33 +1,42 @@
import { Worker } from '@temporalio/worker'; import { Worker } from '@temporalio/worker';
import { URL } from 'url'; import { URL } from 'url';
import path from 'path';
import * as activities from '../../temporal-workflows/src/activities.js'; import * as activities from '../../temporal-workflows/src/activities.js';
// import * as workflows from 'temporal-workflows/workflows.js'; import path from 'node:path';
import './workflows.js'
import 'dotenv/config' import 'dotenv/config'
if (!process.env.TEMPORAL_TASK_QUEUE) throw new Error('TEMPORAL_TASK_QUEUE was missing from env'); if (!process.env.TEMPORAL_TASK_QUEUE) throw new Error('TEMPORAL_TASK_QUEUE was missing from env');
async function run() { async function run() {
const workflowsPath = new URL( // const workflowsPath = new URL(
`../../temporal-workflows/src/workflows${path.extname(import.meta.url)}`, // `./workflows${path.extname(import.meta.url)}`,
import.meta.url // import.meta.url
).pathname // ).pathname
console.log(`workflowsPath=${workflowsPath}`)
// const codePath = new URL('./workflows.js', import.meta.url).pathname
const codePath = path.join(__dirname, './workflows.cjs')
console.log(`codePath=${codePath}`)
const workflowsBundle = {
codePath
}
console.log(`codePath=${codePath}`)
// const workflowOption = () => // const workflowOption = () =>
// process.env.NODE_ENV === 'production' // // process.env.NODE_ENV === 'production'
// (true)
// ? { // ? {
// workflowBundle: { // workflowBundle: {
// // code: workflows // codePath: codePath
// codePath: '/app/temporal-workflows/dist/workflows.js'
// } // }
// } // }
// : { workflowsPath: require.resolve(workflowsPath) } // : {
// workflowsPath: require.resolve(workflowsPath)
// }
// Step 1: Register Workflows and Activities with the Worker and connect to // Step 1: Register Workflows and Activities with the Worker and connect to
// the Temporal server. // the Temporal server.
const worker = await Worker.create({ const worker = await Worker.create({
// ...workflowOption(), // ...workflowOption(),
workflowsPath, workflowsBundle,
activities, activities,
taskQueue: process.env.TEMPORAL_TASK_QUEUE!, taskQueue: process.env.TEMPORAL_TASK_QUEUE!,
}); });

View File

@ -0,0 +1,15 @@
/**
* workflows.ts
*
* Here we export workflows.js from our internal TypeScript package, @futureporn/temporal-workflows
*
* Ideally if we wouldn't need to do this because we would import the code directly from ./index.ts
* However, Temporal doesn't let us do that. It wants us to give a relative path to the workflows.js file.
* This file is a workaround to import the code like we need to, so tsup can bundle it when we run `pnpm build`
*
* This idea comes from https://github.com/nubunto/nx-with-temporal/blob/main/apps/temporal-worker/src/main.ts
*
*
*/
export * from '@futureporn/temporal-workflows/workflows'

View File

@ -0,0 +1,24 @@
import { defineConfig } from "tsup";
import { exec } from 'child_process';
export default defineConfig({
entry: ["src/index.ts", "src/workflows.ts"],
format: ["cjs"],
target: "node20",
clean: true,
sourcemap: true,
/**
* The common package is using the internal packages approach, so it needs to
* be transpiled / bundled together with the deployed code.
*/
noExternal: ["@futureporn/temporal-workflows"],
/**
* We do not use tsup for generating d.ts files because it can not generate type
* the definition maps required for go-to-definition to work in our IDE. We
* use tsc for that.
*/
onSuccess: async () => {
exec('tsc --emitDeclarationOnly');
},
});

View File

@ -1,17 +1,14 @@
{ {
"name": "@futureporn/temporal-workflows", "name": "@futureporn/temporal-workflows",
"version": "0.0.1", "version": "1.0.0",
"private": true, "private": true,
"type": "module", "type": "module",
"exports": { "exports": {
"./workflows.js": "./dist/workflows.js", "./workflows": "./src/workflows.ts",
"./activities.js": "./dist/activities.js" "./activities": "./src/activities.ts"
}, },
"scripts": { "scripts": {
"build": "tsc --build ./tsconfig.json",
"build.watch": "tsc --build -w --preserveWatchOutput",
"lint": "eslint .", "lint": "eslint .",
"clean": "rm -rf dist",
"superclean": "rm -rf node_modules && rm -rf pnpm-lock.yaml && rm -rf dist" "superclean": "rm -rf node_modules && rm -rf pnpm-lock.yaml && rm -rf dist"
}, },
"dependencies": { "dependencies": {