Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[legacy-framework] feat: Implement the new Architecture! #95

Merged
merged 31 commits into from
Apr 13, 2020
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
df432ab
wip
flybayer Apr 11, 2020
ed0157b
working rpc mutation
flybayer Apr 11, 2020
2a65811
queries and mutations working!!
flybayer Apr 11, 2020
f0ecc03
prewarm the lamba
flybayer Apr 11, 2020
efd75e9
update withBlitz config wrapper - remove stuff no longer needed
flybayer Apr 11, 2020
4d69717
switch from `pages` to `routes`
flybayer Apr 11, 2020
129fb22
fix a test issue
flybayer Apr 11, 2020
0e90a03
Merge branch 'canary' into new-arch
flybayer Apr 11, 2020
a94c052
fix cli test
flybayer Apr 11, 2020
574b274
Add file addition and subtraction to transform stream
ryardley Apr 12, 2020
d1d8487
Remove comments
ryardley Apr 12, 2020
fbcba7c
Allow pages and routes
ryardley Apr 12, 2020
31ec2f3
Allow routes folder without context
ryardley Apr 12, 2020
4e4d20e
Tidy up build rules
ryardley Apr 12, 2020
0030ea2
Fix broken transform test
ryardley Apr 12, 2020
8e6f0a5
Use done callback to ensure all events have passed in stream test
ryardley Apr 12, 2020
23877fc
Fix next build breaking
ryardley Apr 12, 2020
2d02074
File generation RPC works
ryardley Apr 12, 2020
2deeadb
Remove commented out code
ryardley Apr 12, 2020
c66d148
Ensure correct jest version so tests run and tidy up
ryardley Apr 13, 2020
902e681
Fix up linting
ryardley Apr 13, 2020
233def9
Tidy up synchroniser
ryardley Apr 13, 2020
a1e185c
Ensure watcher close is run when watchmode is false
ryardley Apr 13, 2020
fafa46c
typo
flybayer Apr 12, 2020
63ddec8
update cli readme
flybayer Apr 13, 2020
37251dc
Fix start error
ryardley Apr 13, 2020
03dec76
Downgrade ts-jest to remove warning
ryardley Apr 13, 2020
597f33e
fix build with static pages
flybayer Apr 13, 2020
a113685
rerun prettier on all files
flybayer Apr 13, 2020
4ebfe46
yarn workspace: nohoist husky and prisma
flybayer Apr 13, 2020
31dd966
add missing dependency
flybayer Apr 13, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/store/app/admin/routes/admin/products/[id].tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Link, useRouter, useQuery} from '@blitzjs/core'
import getProduct from 'app/products/queries/getProduct_rpc'
import getProduct from 'app/products/queries/getProduct'
import ProductForm from 'app/products/components/ProductForm'

export default function() {
Expand Down
2 changes: 1 addition & 1 deletion examples/store/app/admin/routes/admin/products/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {useQuery, Link} from '@blitzjs/core'
import getProducts from 'app/products/queries/getProducts_rpc'
import getProducts from 'app/products/queries/getProducts'

export default function() {
const [products, {status, error}] = useQuery(getProducts)
Expand Down
4 changes: 2 additions & 2 deletions examples/store/app/products/components/ProductForm.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {Form, Field} from 'react-final-form'
import {Product, ProductCreateInput, ProductUpdateInput} from 'prisma'
import createProduct from 'app/products/mutations/createProduct_rpc'
import updateProduct from 'app/products/mutations/updateProduct_rpc'
import createProduct from 'app/products/mutations/createProduct'
import updateProduct from 'app/products/mutations/updateProduct'

type ProductInput = ProductCreateInput | ProductUpdateInput

Expand Down
11 changes: 0 additions & 11 deletions examples/store/app/products/mutations/createProduct_rpc.ts

This file was deleted.

11 changes: 0 additions & 11 deletions examples/store/app/products/mutations/updateProduct_rpc.ts

This file was deleted.

11 changes: 0 additions & 11 deletions examples/store/app/products/queries/getProduct_rpc.ts

This file was deleted.

11 changes: 0 additions & 11 deletions examples/store/app/products/queries/getProducts_rpc.ts

This file was deleted.

3 changes: 3 additions & 0 deletions examples/store/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const {withBlitz} = require('@blitzjs/server')

module.exports = withBlitz({})
5 changes: 0 additions & 5 deletions examples/store/routes/api/products/mutations/createProduct.ts

This file was deleted.

5 changes: 0 additions & 5 deletions examples/store/routes/api/products/mutations/updateProduct.ts

This file was deleted.

5 changes: 0 additions & 5 deletions examples/store/routes/api/products/queries/getProduct.ts

This file was deleted.

5 changes: 0 additions & 5 deletions examples/store/routes/api/products/queries/getProducts.ts

This file was deleted.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"cross-env": "^7.0.0",
"debug": "^4.1.1",
"husky": "^4.2.3",
"jest": "25.3.0",
"jest": "24.9.0",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ryardley is the issue with jest 25?

Copy link
Collaborator

@ryardley ryardley Apr 13, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was finding having multiple versions of jest seemed to cause some tests that should have failed to pass at least on my local. We should try and upgrade it all to 25 to avoid the warning with ts-jest but I vaguely remember having issues with that too so maybe we can do that later or as a separate PR to ensure everything works?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I just checked and tsdx can't handle the newer jest as it throws these errors:

TypeError: Cannot read property 'run' of undefined
    at /Users/rudiyardley/projects/blitz/blitz/node_modules/tsdx/dist/index.js:418:20
error Command failed with exit code 1.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just downgraded ts-jest and everything appears to be working with no warnings.

"lerna": "^3.20.2",
"lint-staged": "^10.0.8",
"npm-run-all": "^4.1.5",
Expand Down
17 changes: 16 additions & 1 deletion packages/core/src/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {BlitzApiRequest, BlitzApiResponse} from '.'
import {serializeError, deserializeError} from 'serialize-error'

export async function rpc(url: string, params: any) {
if (typeof window === 'undefined') return
const result = await window.fetch(url, {
method: 'POST',
credentials: 'same-origin',
Expand All @@ -27,13 +28,27 @@ rpc.warm = (url: string) => {
}
}

export function isomorphicRpc(resolver: any, cacheKey: string) {
if (typeof window !== 'undefined') {
const url = cacheKey.replace(/^app\/_rpc/, '/api')
const rpcFn: any = (params: any) => rpc(url, params)
rpcFn.cacheKey = url

// Warm the lambda
rpc.warm(url)
return rpcFn
} else {
return resolver
}
}

export function rpcHandler(
type: string,
name: string,
resolver: (...args: any) => Promise<any>,
connectDb?: () => any,
) {
return async function(req: BlitzApiRequest, res: BlitzApiResponse) {
return async function (req: BlitzApiRequest, res: BlitzApiResponse) {
const logPrefix = `[${type}:${name}]`
console.log(`${logPrefix} ${req.method} ${JSON.stringify(req.body)} `)

Expand Down
2 changes: 2 additions & 0 deletions packages/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,11 @@
"next-compose-plugins": "2.2.0",
"next-transpile-modules": "3.2.0",
"node-pty": "^0.9.0",
"null-loader": "^3.0.0",
"path-is-absolute": "^2.0.0",
"pirates": "^4.0.1",
"readable-stream": "^3.6.0",
"resolve-bin": "^0.4.0",
"through2": "^3.0.1",
"vinyl": "^2.2.0",
"vinyl-file": "^3.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/server/src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export async function build(config: ServerConfig) {
manifestPath,
writeManifestFile,
includePaths,
} = enhance(config)
} = await enhance(config)

const synchronizer = await synchronizeFiles({
src: rootFolder,
Expand Down
8 changes: 5 additions & 3 deletions packages/server/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {resolve} from 'path'
import {ciLog} from './ciLog'

import {resolveBinAsync} from './resolve-bin-async'
export type ServerConfig = {
rootFolder: string
interceptNextErrors?: boolean
Expand Down Expand Up @@ -34,16 +34,18 @@ const defaults = {
writeManifestFile: true,
}

export function enhance(config: ServerConfig) {
export async function enhance(config: ServerConfig) {
const devFolder = resolve(config.rootFolder, config.devFolder || defaults.devFolder)
const buildFolder = resolve(config.rootFolder, config.buildFolder || defaults.buildFolder)
const manifestPath = resolve(devFolder, config.manifestPath || defaults.manifestPath)
const writeManifestFile =
typeof config.writeManifestFile === 'undefined' ? defaults.writeManifestFile : config.writeManifestFile

const nextBinOrig = await resolveBinAsync('next')

const nextBin = resolve(
config.rootFolder,
config.interceptNextErrors ? defaults.nextBinPatched : defaults.nextBin,
config.interceptNextErrors ? defaults.nextBinPatched : nextBinOrig,
)

return ciLog(
Expand Down
2 changes: 1 addition & 1 deletion packages/server/src/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export async function dev(config: ServerConfig) {
manifestPath,
writeManifestFile,
includePaths,
} = enhance({
} = await enhance({
...config,
interceptNextErrors: true,
})
Expand Down
2 changes: 1 addition & 1 deletion packages/server/src/prod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {nextStart} from './next-utils'
import {build} from './build'

export async function prod(config: ServerConfig) {
const {rootFolder, nextBin} = enhance(config)
const {rootFolder, nextBin} = await enhance(config)
await build(config)
await nextStart(nextBin, rootFolder)
}
12 changes: 12 additions & 0 deletions packages/server/src/resolve-bin-async.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import resolveBin from 'resolve-bin'

export function resolveBinAsync(pkg: string) {
return new Promise<string>((resolve, reject) => {
resolveBin(pkg, (err, bin) => {
if (err) {
reject(err)
}
resolve(bin)
})
})
}
5 changes: 5 additions & 0 deletions packages/server/src/resolve-bin.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
declare module 'resolve-bin' {
type Cb = (err: Error, bin: string) => void
type Options = {executable?: boolean}
export default function resolveBin(mod: string, opts: Cb | Options, callback?: Cb): void
}
73 changes: 40 additions & 33 deletions packages/server/src/synchronizer/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {unlink} from './unlink'
import {dest} from 'vinyl-fs'
import {transformPage} from './transform-page'
import pagesFolder from './rules/pages-folder'
import rpc from './rules/rpc'
import {Manifest, createManifestFile, setManifestEntry} from './manifest'
import {watch} from './watch'
import {FSWatcher} from 'chokidar'
Expand All @@ -10,6 +11,8 @@ import File from 'vinyl'
import fg from 'fast-glob'
import {remove, pathExists, ensureDir} from 'fs-extra'
import {ciLog} from '../ciLog'
import {runRule} from './rules-runner'
import through from 'through2'

type SynchronizeFilesInput = {
src: string
Expand All @@ -34,13 +37,20 @@ async function clean(path: string) {
return await ensureDir(path)
}

function countStream(stream: NodeJS.WritableStream, cb: (count: number) => void) {
const countStream = (cb: (count: number) => void) => {
let count = 0
return stream.on('data', () => {
return through.obj((_, __, next) => {
cb(++count)
next()
})
}

// TODO: handle files possibly corrupted out of sync
// * how can I know that an entry is out of sync?
// * add stat info modified date in the manifest
// * stat the entry for modified date ahead of time
// * if the dates are different then the entry is invalid and should be waited on

export async function synchronizeFiles({
dest: destPath,
src: srcPath,
Expand All @@ -57,45 +67,42 @@ export async function synchronizeFiles({
cwd: srcPath,
}

// TODO: handle files possibly corrupted out of sync
// * how can I know that an entry is out of sync?
// * add stat info modified date in the manifest
// * stat the entry for modified date ahead of time
// * if the dates are different then the entry is invalid and should be waited on

const entries = fg.sync(includePaths, {ignore: options.ignored, cwd: options.cwd})
const manifest = Manifest.create()
const {stream, watcher} = watch(includePaths, options)
const {stream: watchStream, watcher} = watch(includePaths, options)

await clean(destPath)

const createStream = () =>
return await new Promise((resolve, reject) => {
pipeline(
stream,
transformPage({
sourceFolder: srcPath,
appFolder: 'app',
folderName: 'routes',
}),
watchStream,

// Rules
runRule(pagesFolder({srcPath})),
runRule(rpc({srcPath})),

// File sync
gulpIf(isUnlinkFile, unlink(destPath), dest(destPath)),

// Maintain build manifest
setManifestEntry(manifest),
createManifestFile(manifest, manifestPath),
gulpIf(writeManifestFile, dest(srcPath)),
)

await clean(destPath)
countStream((count) => {
if (count >= entries.length) {
ciLog('Stream files have been created. Here is a manifest.', manifest.toObject())

return await new Promise(resolve => {
// TODO: add timeout/error?
countStream(createStream(), count => {
if (count >= entries.length) {
ciLog('Stream files have been created. Here is a manifest.', manifest.toObject())

resolve({
stream,
watcher,
manifest,
})
}
})
resolve({
stream: watchStream,
watcher,
manifest,
})
}
}),
(err) => {
reject(err)
},
)
})
}

Expand Down
Loading