Skip to content

Commit

Permalink
Make ponyfill only export the explicitly typed values (#124)
Browse files Browse the repository at this point in the history
  • Loading branch information
Schniz committed Aug 31, 2022
1 parent 1bd7684 commit 0cede1e
Show file tree
Hide file tree
Showing 8 changed files with 837 additions and 670 deletions.
5 changes: 5 additions & 0 deletions .changeset/tall-lies-invite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@edge-runtime/ponyfill': patch
---

Only export the specific values from the global scope as we define in our types
5 changes: 5 additions & 0 deletions .changeset/thick-pets-brush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@edge-runtime/primitives': patch
---

Mark the createCaches export as nullable as it does not exist in Edge Runtime
8 changes: 6 additions & 2 deletions packages/ponyfill/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,19 @@
],
"devDependencies": {
"@edge-runtime/jest-environment": "workspace:1.1.0-beta.32",
"@edge-runtime/primitives": "workspace:1.1.0-beta.32"
"@edge-runtime/primitives": "workspace:1.1.0-beta.32",
"@edge-runtime/vm": "workspace:^1.1.0-beta.32",
"acorn": "8.8.0",
"acorn-loose": "8.3.0",
"acorn-walk": "8.2.0"
},
"files": [
"src"
],
"scripts": {
"clean": "rm -rf node_modules",
"test": "pnpm test:edge && pnpm test:node",
"test:edge": "EDGE_RUNTIME_EXISTS=true jest --env=@edge-runtime/jest-environment",
"test:edge": "EDGE_RUNTIME_EXISTS=true jest --env=@edge-runtime/jest-environment --testPathIgnorePatterns='.node.test.ts$'",
"test:node": "jest --env=node"
},
"license": "MPLv2",
Expand Down
42 changes: 41 additions & 1 deletion packages/ponyfill/src/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,42 @@
module.exports =
typeof EdgeRuntime === 'string' ? self : require('@edge-runtime/primitives')
typeof EdgeRuntime === 'string' ? edge() : require('@edge-runtime/primitives')

function edge() {
return {
AbortController,
AbortSignal,
Blob,
Cache,
CacheStorage,
Crypto,
CryptoKey,
Event,
EventTarget,
FetchEvent,
File,
FormData,
Headers,
PromiseRejectionEvent,
ReadableStream,
ReadableStreamBYOBReader,
ReadableStreamDefaultReader,
Request,
Response,
SubtleCrypto,
TextDecoder,
TextEncoder,
TransformStream,
URL,
URLPattern,
URLSearchParams,
WritableStream,
WritableStreamDefaultWriter,
atob,
btoa,
caches,
console,
crypto,
fetch,
structuredClone,
}
}
4 changes: 4 additions & 0 deletions packages/ponyfill/test/acorn.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
declare module 'acorn-loose' {
const exported: typeof import('acorn')
export = exported
}
73 changes: 73 additions & 0 deletions packages/ponyfill/test/compliance-with-primitives.node.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { parse } from 'acorn-loose'
import { promises as fs } from 'fs'
import { simple } from 'acorn-walk'
import { EdgeVM } from '@edge-runtime/vm'

test('exports all primitives in Edge Runtime', async () => {
const exportedNames = await getExportedNames()

const anyObject = exportedNames.reduce(
(acc: Record<string, any>, name: string) => {
acc[name] = expect.anything()
return acc
},
{}
)

const runtime = new EdgeVM({
codeGeneration: { strings: false, wasm: false },
})
const result = runtime.require(require.resolve('..'))

for (const key of LIMBO_STATE) {
delete anyObject[key]
delete result[key]
}

expect(result).toEqual(anyObject)
})

test('exports all primitives in Node.js', async () => {
const exportedNames = await getExportedNames()

const anyObject = exportedNames.reduce(
(acc: Record<string, any>, name: string) => {
acc[name] = expect.anything()
return acc
},
{}
)

const result = { ...require('..') }

for (const key of LIMBO_STATE) {
delete anyObject[key]
delete result[key]
}

expect(result).toEqual(anyObject)
})

async function getExportedNames() {
const typesPath = require.resolve('@edge-runtime/primitives/types/index.d.ts')
const typesContents = await fs.readFile(typesPath, 'utf8')
const ast = parse(typesContents, { ecmaVersion: 'latest' })
const exportedNames: string[] = []
simple(ast, {
ExportNamedDeclaration(node: any) {
for (const specifier of node.specifiers) {
if (specifier.exported?.name) {
exportedNames.push(specifier.exported.name)
}
}
},
})
return exportedNames
}

export const LIMBO_STATE = [
'createCaches',
'DOMException',
'setGlobalDispatcher',
'getGlobalDispatcher',
]
12 changes: 7 additions & 5 deletions packages/primitives/type-definitions/cache.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
export function createCaches(): {
cacheStorage: () => CacheStorage
Cache: typeof Cache
CacheStorage: typeof CacheStorage
}
export function createCaches():
| undefined
| {
cacheStorage: () => CacheStorage
Cache: typeof Cache
CacheStorage: typeof CacheStorage
}

export const caches: CacheStorage

Expand Down
Loading

1 comment on commit 0cede1e

@vercel
Copy link

@vercel vercel bot commented on 0cede1e Aug 31, 2022

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

edge-runtime – ./

edge-runtime.vercel.app
edge-runtime.vercel.sh
edge-runtime-git-main.vercel.sh

Please sign in to comment.