From 46a8215092c3e0cd56703b6ceb3c5a939d53c35c Mon Sep 17 00:00:00 2001
From: Jack Hanford <jackhanford@gmail.com>
Date: Thu, 11 Nov 2021 11:21:47 -0800
Subject: consolidate empty files / references to one empty.tsx

---
 packages/bun-framework-next/server-polyfills.tsx | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'packages/bun-framework-next/server-polyfills.tsx')

diff --git a/packages/bun-framework-next/server-polyfills.tsx b/packages/bun-framework-next/server-polyfills.tsx
index 474ee6ec9..d34c08fc5 100644
--- a/packages/bun-framework-next/server-polyfills.tsx
+++ b/packages/bun-framework-next/server-polyfills.tsx
@@ -13,6 +13,7 @@ class URL {
   }
 }
 var onlyChildPolyfill = React.Children.only;
+
 React.Children.only = function (children) {
   if (children && typeof children === "object" && children.length == 1) {
     return onlyChildPolyfill(children[0]);
@@ -20,6 +21,7 @@ React.Children.only = function (children) {
 
   return onlyChildPolyfill(children);
 };
+
 globalThis.URL = URL;
 
 import { TextEncoder, TextDecoder } from "./text-encoder-polyfill";
-- 
cgit v1.2.3


From 6ee673095cbddc97a56bae7a512a5271d4a977a2 Mon Sep 17 00:00:00 2001
From: Jack Hanford <jackhanford@gmail.com>
Date: Mon, 15 Nov 2021 15:45:37 -0800
Subject: continue fixing typescript errors

---
 packages/bun-framework-next/client.development.tsx | 59 +++++++++++++---------
 .../bun-framework-next/fallback.development.tsx    |  3 +-
 packages/bun-framework-next/package.json           |  3 ++
 packages/bun-framework-next/page-loader.ts         | 16 ++++--
 packages/bun-framework-next/server-polyfills.tsx   | 12 ++++-
 packages/bun-framework-next/server.development.tsx |  1 +
 pnpm-lock.yaml                                     | 31 ++++++++++++
 7 files changed, 93 insertions(+), 32 deletions(-)

(limited to 'packages/bun-framework-next/server-polyfills.tsx')

diff --git a/packages/bun-framework-next/client.development.tsx b/packages/bun-framework-next/client.development.tsx
index f3d8d39e5..bf03af289 100644
--- a/packages/bun-framework-next/client.development.tsx
+++ b/packages/bun-framework-next/client.development.tsx
@@ -1,10 +1,20 @@
+/// <reference types="react-dom/experimental" />
+
 globalThis.global = globalThis;
 globalThis.Bun_disableCSSImports = true;
 
 import * as React from "react";
+
 var onlyChildPolyfill = React.Children.only;
-React.Children.only = function (children) {
-  if (children && typeof children === "object" && children.length == 1) {
+
+React.Children.only = function only(
+  children: React.ReactNode | React.ReactNode[]
+) {
+  if (
+    children &&
+    typeof children === "object" &&
+    (children as any).length == 1
+  ) {
     return onlyChildPolyfill(children[0]);
   }
 
@@ -23,9 +33,7 @@ import Router, {
   PrivateRouteInfo,
 } from "next/dist/shared/lib/router/router";
 
-const App = NextApp;
-
-import * as NextRouteLoader from "next/dist/client/route-loader";
+import NextRouteLoader from "next/dist/client/route-loader";
 import { isDynamicRoute } from "next/dist/shared/lib/router/utils/is-dynamic";
 import {
   urlQueryToSearchParams,
@@ -41,8 +49,11 @@ import {
   createRouter,
   makePublicRouterInstance,
 } from "next/dist/client/router";
+
 export const emitter: MittEmitter<string> = mitt();
 
+const App = NextApp;
+
 declare global {
   interface Window {
     /* test fns */
@@ -102,7 +113,8 @@ type RenderRouteInfo = PrivateRouteInfo & {
 
 const nextDataTag = document.getElementById("__NEXT_DATA__");
 
-const data: typeof window["__NEXT_DATA__"] = nextDataTag
+// pages is added at runtime and doesn't exist in Next types
+const data: NEXT_DATA & { pages: Record<string, string[]> } = nextDataTag
   ? JSON.parse(document.getElementById("__NEXT_DATA__")!.textContent!)
   : nextDataFromBunData();
 
@@ -116,12 +128,14 @@ const {
   buildId,
   assetPrefix,
   runtimeConfig,
+  // Todo, revist this constant when supporting dynamic()
   dynamicIds,
   isFallback,
   locale,
   locales,
   domainLocales,
   isPreview,
+  pages,
 } = data;
 
 const prefix: string = assetPrefix || "";
@@ -138,24 +152,19 @@ if (hasBasePath(asPath)) {
   asPath = delBasePath(asPath);
 }
 
-export const pageLoader: PageLoader = new PageLoader(
-  buildId,
-  prefix,
-  data.pages
-);
+export const pageLoader: PageLoader = new PageLoader(buildId, prefix, pages);
 
 const headManager: {
   mountedInstances: Set<unknown>;
   updateHead: (head: JSX.Element[]) => void;
 } = initHeadManager();
-const appElement: HTMLElement | null = document.getElementById("__next");
 
 export let router: Router;
-let CachedApp: AppComponent = App,
-  onPerfEntry: (metric: any) => void;
 
-export default function boot(EntryPointNamespace, loader) {
-  _boot(EntryPointNamespace).then(() => {}, false);
+let CachedApp: AppComponent = null;
+
+export default function boot(EntryPointNamespace) {
+  _boot(EntryPointNamespace, false);
 }
 
 class Container extends React.Component<{
@@ -274,7 +283,7 @@ let reactRoot: any = null;
 const USE_REACT_18 = "hydrateRoot" in ReactDOM;
 
 export async function _boot(EntryPointNamespace, isError) {
-  NextRouteLoader.default.getClientBuildManifest = () => Promise.resolve({});
+  NextRouteLoader.getClientBuildManifest = () => Promise.resolve({});
 
   const PageComponent = EntryPointNamespace.default;
 
@@ -293,6 +302,7 @@ export async function _boot(EntryPointNamespace, isError) {
 
     if (appSrc) {
       const AppModule = await import(appSrc);
+
       console.assert(
         AppModule.default,
         appSrc + " must have a default export'd React component"
@@ -332,7 +342,9 @@ export async function _boot(EntryPointNamespace, isError) {
   });
 
   globalThis.next.router = router;
+
   const domEl = document.querySelector("#__next");
+
   const reactEl = (
     <TopLevelRender
       App={CachedApp}
@@ -361,9 +373,9 @@ export async function _boot(EntryPointNamespace, isError) {
   }
 }
 
-function TopLevelRender({ App, Component, props, scroll }) {
+function TopLevelRender({ App, Component, props }) {
   return (
-    <AppContainer scroll={scroll}>
+    <AppContainer>
       <App Component={Component} {...props}></App>
     </AppContainer>
   );
@@ -381,18 +393,15 @@ export function render(props) {
 }
 
 export function renderError(e) {
-  const reactEl = (
-    <AppContainer>
-      <App Component={<div>UH OH!!!!</div>} pageProps={data.props}></App>
-    </AppContainer>
-  );
+  // TODO verify this works
+  const reactEl = <AppContainer>{null}</AppContainer>;
 
   if (USE_REACT_18) {
     if (!reactRoot) {
       const domEl = document.querySelector("#__next");
 
       // Unlike with createRoot, you don't need a separate root.render() call here
-      reactRoot = ReactDOM.createRoot(domEl, reactEl);
+      reactRoot = ReactDOM.hydrateRoot(domEl, reactEl);
     } else {
       reactRoot.render(reactEl);
     }
diff --git a/packages/bun-framework-next/fallback.development.tsx b/packages/bun-framework-next/fallback.development.tsx
index 54d31d5f5..460b5e165 100644
--- a/packages/bun-framework-next/fallback.development.tsx
+++ b/packages/bun-framework-next/fallback.development.tsx
@@ -1,5 +1,5 @@
 import { insertStyleSheet } from "./page-loader";
-import type { FallbackMessageContainer } from "../../../src/api/schema";
+import type { FallbackMessageContainer } from "../../src/api/schema";
 
 var once = false;
 function insertNextHeadCount() {
@@ -65,6 +65,7 @@ function renderFallback({ router }: FallbackMessageContainer) {
 }
 
 export default function render(props: FallbackMessageContainer) {
+  // @ts-expect-error bun:error.js is real
   return import("/bun:error.js").then(({ renderFallbackError }) => {
     return renderFallback(props).then(
       () => {
diff --git a/packages/bun-framework-next/package.json b/packages/bun-framework-next/package.json
index b07199615..ea459412a 100644
--- a/packages/bun-framework-next/package.json
+++ b/packages/bun-framework-next/package.json
@@ -11,12 +11,15 @@
   "author": "",
   "license": "MIT",
   "dependencies": {
+    "bun-framework-next": "^12.0.4",
     "react-is": "^17.0.2"
   },
   "peerDependencies": {
     "next": "^12.0.0"
   },
   "devDependencies": {
+    "@types/react": "^17.0.34",
+    "@types/react-dom": "^17.0.11",
     "next": "^12.0.0",
     "react-refresh": "^0.10.0",
     "typescript": "^4.4.4"
diff --git a/packages/bun-framework-next/page-loader.ts b/packages/bun-framework-next/page-loader.ts
index 2a8b402ad..3b31387d8 100644
--- a/packages/bun-framework-next/page-loader.ts
+++ b/packages/bun-framework-next/page-loader.ts
@@ -1,4 +1,6 @@
-import NextPageLoader from "next/dist/client/page-loader";
+import NextPageLoader, {
+  GoodPageCache as NextGoodPageCache,
+} from "next/dist/client/page-loader";
 import getAssetPathFromRoute from "next/dist/shared/lib/router/utils/get-asset-path-from-route";
 
 export function insertStyleSheet(url: string) {
@@ -10,8 +12,9 @@ export function insertStyleSheet(url: string) {
     const link = document.createElement("link");
     link.rel = "stylesheet";
 
-    link.onload = () => resolve();
-    link.onerror = () => reject();
+    // marking this resolve as void seems to break other things
+    link.onload = resolve;
+    link.onerror = reject;
 
     link.href = url;
 
@@ -19,6 +22,11 @@ export function insertStyleSheet(url: string) {
   });
 }
 
+interface GoodPageCache extends NextGoodPageCache {
+  __N_SSG: boolean;
+  __N_SSP: boolean;
+}
+
 export default class PageLoader extends NextPageLoader {
   constructor(_, __, pages) {
     super(_, __);
@@ -70,7 +78,7 @@ export default class PageLoader extends NextPageLoader {
   };
 
   prefetch() {
-    return Promise.resolve({});
+    return Promise.resolve();
   }
 
   async loadPage(route: string): Promise<GoodPageCache> {
diff --git a/packages/bun-framework-next/server-polyfills.tsx b/packages/bun-framework-next/server-polyfills.tsx
index d34c08fc5..8942154b7 100644
--- a/packages/bun-framework-next/server-polyfills.tsx
+++ b/packages/bun-framework-next/server-polyfills.tsx
@@ -7,15 +7,23 @@ globalThis.Buffer = Buffer;
 import * as React from "react";
 
 class URL {
-  constructor(base, source) {
+  pathname: string;
+  href: string;
+
+  constructor(base: string, source: string) {
     this.pathname = source;
     this.href = base + source;
   }
 }
+
 var onlyChildPolyfill = React.Children.only;
 
 React.Children.only = function (children) {
-  if (children && typeof children === "object" && children.length == 1) {
+  if (
+    children &&
+    typeof children === "object" &&
+    (children as any).length == 1
+  ) {
     return onlyChildPolyfill(children[0]);
   }
 
diff --git a/packages/bun-framework-next/server.development.tsx b/packages/bun-framework-next/server.development.tsx
index 96ba55812..fd2a7b620 100644
--- a/packages/bun-framework-next/server.development.tsx
+++ b/packages/bun-framework-next/server.development.tsx
@@ -1,6 +1,7 @@
 import nextPackage from "next/package.json";
 import "./server-polyfills";
 import { render } from "./renderDocument";
+import { ResolveError } from "../../src/runtime/errors";
 
 const { version } = nextPackage;
 if (
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b96e023bc..4fa5982b1 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -43,6 +43,9 @@ importers:
 
   packages/bun-framework-next:
     specifiers:
+      '@types/react': ^17.0.34
+      '@types/react-dom': ^17.0.11
+      bun-framework-next: ^12.0.4
       next: ^12.0.0
       react-is: ^17.0.2
       react-refresh: ^0.10.0
@@ -50,6 +53,8 @@ importers:
     dependencies:
       react-is: 17.0.2
     devDependencies:
+      '@types/react': 17.0.34
+      '@types/react-dom': 17.0.11
       next: 12.0.3_react-dom@17.0.2+react@17.0.2
       react-refresh: 0.10.0
       typescript: 4.4.4
@@ -279,12 +284,34 @@ packages:
   /@types/node/16.11.4:
     resolution: {integrity: sha512-TMgXmy0v2xWyuCSCJM6NCna2snndD8yvQF67J29ipdzMcsPa9u+o0tjF5+EQNdhcuZplYuouYqpc4zcd5I6amQ==}
 
+  /@types/prop-types/15.7.4:
+    resolution: {integrity: sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==}
+    dev: true
+
   /@types/puppeteer/5.4.4:
     resolution: {integrity: sha512-3Nau+qi69CN55VwZb0ATtdUAlYlqOOQ3OfQfq0Hqgc4JMFXiQT/XInlwQ9g6LbicDslE6loIFsXFklGh5XmI6Q==}
     dependencies:
       '@types/node': 16.11.4
     dev: true
 
+  /@types/react-dom/17.0.11:
+    resolution: {integrity: sha512-f96K3k+24RaLGVu/Y2Ng3e1EbZ8/cVJvypZWd7cy0ofCBaf2lcM46xNhycMZ2xGwbBjRql7hOlZ+e2WlJ5MH3Q==}
+    dependencies:
+      '@types/react': 17.0.34
+    dev: true
+
+  /@types/react/17.0.34:
+    resolution: {integrity: sha512-46FEGrMjc2+8XhHXILr+3+/sTe3OfzSPU9YGKILLrUYbQ1CLQC9Daqo1KzENGXAWwrFwiY0l4ZbF20gRvgpWTg==}
+    dependencies:
+      '@types/prop-types': 15.7.4
+      '@types/scheduler': 0.16.2
+      csstype: 3.0.10
+    dev: true
+
+  /@types/scheduler/0.16.2:
+    resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==}
+    dev: true
+
   /@types/yauzl/2.9.2:
     resolution: {integrity: sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==}
     requiresBuild: true
@@ -749,6 +776,10 @@ packages:
       postcss: 8.2.15
     dev: true
 
+  /csstype/3.0.10:
+    resolution: {integrity: sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==}
+    dev: true
+
   /data-uri-to-buffer/3.0.1:
     resolution: {integrity: sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==}
     engines: {node: '>= 6'}
-- 
cgit v1.2.3


From 7f62169b5e50a6c01d261915a827bfcea98d522d Mon Sep 17 00:00:00 2001
From: Jack Hanford <jackhanford@gmail.com>
Date: Tue, 16 Nov 2021 10:22:22 -0800
Subject: add prettier to root

---
 package.json                                       |   4 +-
 packages/bun-framework-next/package.json           |   4 +-
 packages/bun-framework-next/server-polyfills.tsx   |  14 +-
 .../bun-framework-next/text-encoder-polyfill.js    | 302 ---------------------
 pnpm-lock.yaml                                     |   6 +-
 5 files changed, 10 insertions(+), 320 deletions(-)
 delete mode 100644 packages/bun-framework-next/text-encoder-polyfill.js

(limited to 'packages/bun-framework-next/server-polyfills.tsx')

diff --git a/package.json b/package.json
index 563000fa7..8955f7ef2 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,6 @@
     "highlight.js": "^11.3.1",
     "moment": "^2.29.1",
     "peechy": "0.4.20",
-    "prettier": "latest",
     "puppeteer": "^10.2.0",
     "react": "^17.0.2",
     "react-dom": "^17.0.2"
@@ -15,7 +14,8 @@
   },
   "devDependencies": {
     "@types/node": "^16.9.2",
-    "@types/puppeteer": "^5.4.4"
+    "@types/puppeteer": "^5.4.4",
+    "prettier": "^2.4.1"
   },
   "version": "0.0.0"
 }
diff --git a/packages/bun-framework-next/package.json b/packages/bun-framework-next/package.json
index 953ca29c3..d715a8ba4 100644
--- a/packages/bun-framework-next/package.json
+++ b/packages/bun-framework-next/package.json
@@ -11,7 +11,9 @@
   "author": "",
   "license": "MIT",
   "dependencies": {
-    "react-is": "^17.0.2"
+    "fast-text-encoding": "^1.0.3",
+    "react-is": "^17.0.2",
+    "url-polyfill": "^1.1.12"
   },
   "peerDependencies": {
     "next": "^12.0.0"
diff --git a/packages/bun-framework-next/server-polyfills.tsx b/packages/bun-framework-next/server-polyfills.tsx
index 8942154b7..887621978 100644
--- a/packages/bun-framework-next/server-polyfills.tsx
+++ b/packages/bun-framework-next/server-polyfills.tsx
@@ -1,21 +1,13 @@
 globalThis.global = globalThis;
 
 import { Buffer } from "buffer";
+import { URL } from "url-polyfill";
+import { TextEncoder, TextDecoder } from "fast-text-encoding";
 
 globalThis.Buffer = Buffer;
 
 import * as React from "react";
 
-class URL {
-  pathname: string;
-  href: string;
-
-  constructor(base: string, source: string) {
-    this.pathname = source;
-    this.href = base + source;
-  }
-}
-
 var onlyChildPolyfill = React.Children.only;
 
 React.Children.only = function (children) {
@@ -32,7 +24,5 @@ React.Children.only = function (children) {
 
 globalThis.URL = URL;
 
-import { TextEncoder, TextDecoder } from "./text-encoder-polyfill";
-
 globalThis.TextEncoder ||= TextEncoder;
 globalThis.TextDecoder ||= TextDecoder;
diff --git a/packages/bun-framework-next/text-encoder-polyfill.js b/packages/bun-framework-next/text-encoder-polyfill.js
deleted file mode 100644
index 3dd95009f..000000000
--- a/packages/bun-framework-next/text-encoder-polyfill.js
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright 2017 Sam Thorogood. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-/**
- * @fileoverview Polyfill for TextEncoder and TextDecoder.
- *
- * You probably want `text.min.js`, and not this file directly.
- */
-
-// used for FastTextDecoder
-const validUtfLabels = ["utf-8", "utf8", "unicode-1-1-utf-8"];
-
-/**
- * @constructor
- */
-function FastTextEncoder() {
-  // This does not accept an encoding, and always uses UTF-8:
-  //   https://www.w3.org/TR/encoding/#dom-textencoder
-}
-
-Object.defineProperty(FastTextEncoder.prototype, "encoding", {
-  value: "utf-8",
-});
-
-/**
- * @param {string} string
- * @param {{stream: boolean}=} options
- * @return {!Uint8Array}
- */
-FastTextEncoder.prototype["encode"] = function (
-  string,
-  options = { stream: false }
-) {
-  if (options.stream) {
-    throw new Error(`Failed to encode: the 'stream' option is unsupported.`);
-  }
-
-  let pos = 0;
-  const len = string.length;
-
-  let at = 0; // output position
-  let tlen = Math.max(32, len + (len >>> 1) + 7); // 1.5x size
-  let target = new Uint8Array((tlen >>> 3) << 3); // ... but at 8 byte offset
-
-  while (pos < len) {
-    let value = string.charCodeAt(pos++);
-    if (value >= 0xd800 && value <= 0xdbff) {
-      // high surrogate
-      if (pos < len) {
-        const extra = string.charCodeAt(pos);
-        if ((extra & 0xfc00) === 0xdc00) {
-          ++pos;
-          value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;
-        }
-      }
-      if (value >= 0xd800 && value <= 0xdbff) {
-        continue; // drop lone surrogate
-      }
-    }
-
-    // expand the buffer if we couldn't write 4 bytes
-    if (at + 4 > target.length) {
-      tlen += 8; // minimum extra
-      tlen *= 1.0 + (pos / string.length) * 2; // take 2x the remaining
-      tlen = (tlen >>> 3) << 3; // 8 byte offset
-
-      const update = new Uint8Array(tlen);
-      update.set(target);
-      target = update;
-    }
-
-    if ((value & 0xffffff80) === 0) {
-      // 1-byte
-      target[at++] = value; // ASCII
-      continue;
-    } else if ((value & 0xfffff800) === 0) {
-      // 2-byte
-      target[at++] = ((value >>> 6) & 0x1f) | 0xc0;
-    } else if ((value & 0xffff0000) === 0) {
-      // 3-byte
-      target[at++] = ((value >>> 12) & 0x0f) | 0xe0;
-      target[at++] = ((value >>> 6) & 0x3f) | 0x80;
-    } else if ((value & 0xffe00000) === 0) {
-      // 4-byte
-      target[at++] = ((value >>> 18) & 0x07) | 0xf0;
-      target[at++] = ((value >>> 12) & 0x3f) | 0x80;
-      target[at++] = ((value >>> 6) & 0x3f) | 0x80;
-    } else {
-      continue; // out of range
-    }
-
-    target[at++] = (value & 0x3f) | 0x80;
-  }
-
-  // Use subarray if slice isn't supported (IE11). This will use more memory
-  // because the original array still exists.
-  return target.slice ? target.slice(0, at) : target.subarray(0, at);
-};
-
-/**
- * @constructor
- * @param {string=} utfLabel
- * @param {{fatal: boolean}=} options
- */
-function FastTextDecoder(utfLabel = "utf-8", options = { fatal: false }) {
-  if (validUtfLabels.indexOf(utfLabel.toLowerCase()) === -1) {
-    throw new RangeError(
-      `Failed to construct 'TextDecoder': The encoding label provided ('${utfLabel}') is invalid.`
-    );
-  }
-  if (options.fatal) {
-    throw new Error(
-      `Failed to construct 'TextDecoder': the 'fatal' option is unsupported.`
-    );
-  }
-}
-
-Object.defineProperty(FastTextDecoder.prototype, "encoding", {
-  value: "utf-8",
-});
-
-Object.defineProperty(FastTextDecoder.prototype, "fatal", { value: false });
-
-Object.defineProperty(FastTextDecoder.prototype, "ignoreBOM", {
-  value: false,
-});
-
-/**
- * @param {!Uint8Array} bytes
- * @return {string}
- */
-function decodeBuffer(bytes) {
-  return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString(
-    "utf-8"
-  );
-}
-
-/**
- * @param {!Uint8Array} bytes
- * @return {string}
- */
-function decodeSyncXHR(bytes) {
-  const b = new Blob([bytes], { type: "text/plain;charset=UTF-8" });
-  const u = URL.createObjectURL(b);
-
-  // This hack will fail in non-Edgium Edge because sync XHRs are disabled (and
-  // possibly in other places), so ensure there's a fallback call.
-  try {
-    const x = new XMLHttpRequest();
-    x.open("GET", u, false);
-    x.send();
-    return x.responseText;
-  } catch (e) {
-    return decodeFallback(bytes);
-  } finally {
-    URL.revokeObjectURL(u);
-  }
-}
-
-/**
- * @param {!Uint8Array} bytes
- * @return {string}
- */
-function decodeFallback(bytes) {
-  let inputIndex = 0;
-
-  // Create a working buffer for UTF-16 code points, but don't generate one
-  // which is too large for small input sizes. UTF-8 to UCS-16 conversion is
-  // going to be at most 1:1, if all code points are ASCII. The other extreme
-  // is 4-byte UTF-8, which results in two UCS-16 points, but this is still 50%
-  // fewer entries in the output.
-  const pendingSize = Math.min(256 * 256, bytes.length + 1);
-  const pending = new Uint16Array(pendingSize);
-  const chunks = [];
-  let pendingIndex = 0;
-
-  for (;;) {
-    const more = inputIndex < bytes.length;
-
-    // If there's no more data or there'd be no room for two UTF-16 values,
-    // create a chunk. This isn't done at the end by simply slicing the data
-    // into equal sized chunks as we might hit a surrogate pair.
-    if (!more || pendingIndex >= pendingSize - 1) {
-      // nb. .apply and friends are *really slow*. Low-hanging fruit is to
-      // expand this to literally pass pending[0], pending[1], ... etc, but
-      // the output code expands pretty fast in this case.
-      chunks.push(
-        String.fromCharCode.apply(null, pending.subarray(0, pendingIndex))
-      );
-
-      if (!more) {
-        return chunks.join("");
-      }
-
-      // Move the buffer forward and create another chunk.
-      bytes = bytes.subarray(inputIndex);
-      inputIndex = 0;
-      pendingIndex = 0;
-    }
-
-    // The native TextDecoder will generate "REPLACEMENT CHARACTER" where the
-    // input data is invalid. Here, we blindly parse the data even if it's
-    // wrong: e.g., if a 3-byte sequence doesn't have two valid continuations.
-
-    const byte1 = bytes[inputIndex++];
-    if ((byte1 & 0x80) === 0) {
-      // 1-byte or null
-      pending[pendingIndex++] = byte1;
-    } else if ((byte1 & 0xe0) === 0xc0) {
-      // 2-byte
-      const byte2 = bytes[inputIndex++] & 0x3f;
-      pending[pendingIndex++] = ((byte1 & 0x1f) << 6) | byte2;
-    } else if ((byte1 & 0xf0) === 0xe0) {
-      // 3-byte
-      const byte2 = bytes[inputIndex++] & 0x3f;
-      const byte3 = bytes[inputIndex++] & 0x3f;
-      pending[pendingIndex++] = ((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3;
-    } else if ((byte1 & 0xf8) === 0xf0) {
-      // 4-byte
-      const byte2 = bytes[inputIndex++] & 0x3f;
-      const byte3 = bytes[inputIndex++] & 0x3f;
-      const byte4 = bytes[inputIndex++] & 0x3f;
-
-      // this can be > 0xffff, so possibly generate surrogates
-      let codepoint =
-        ((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;
-      if (codepoint > 0xffff) {
-        // codepoint &= ~0x10000;
-        codepoint -= 0x10000;
-        pending[pendingIndex++] = ((codepoint >>> 10) & 0x3ff) | 0xd800;
-        codepoint = 0xdc00 | (codepoint & 0x3ff);
-      }
-      pending[pendingIndex++] = codepoint;
-    } else {
-      // invalid initial byte
-    }
-  }
-}
-
-// Decoding a string is pretty slow, but use alternative options where possible.
-let decodeImpl = decodeFallback;
-if (typeof Buffer === "function" && Buffer.from) {
-  // Buffer.from was added in Node v5.10.0 (2015-11-17).
-  decodeImpl = decodeBuffer;
-} else if (
-  typeof Blob === "function" &&
-  typeof URL === "function" &&
-  typeof URL.createObjectURL === "function"
-) {
-  // Blob and URL.createObjectURL are available from IE10, Safari 6, Chrome 19
-  // (all released in 2012), Firefox 19 (2013), ...
-  decodeImpl = decodeSyncXHR;
-}
-
-/**
- * @param {(!ArrayBuffer|!ArrayBufferView)} buffer
- * @param {{stream: boolean}=} options
- * @return {string}
- */
-FastTextDecoder.prototype["decode"] = function (
-  buffer,
-  options = { stream: false }
-) {
-  if (options["stream"]) {
-    throw new Error(`Failed to decode: the 'stream' option is unsupported.`);
-  }
-
-  let bytes;
-
-  if (buffer instanceof Uint8Array) {
-    // Accept Uint8Array instances as-is.
-    bytes = buffer;
-  } else if (buffer.buffer instanceof ArrayBuffer) {
-    // Look for ArrayBufferView, which isn't a real type, but basically
-    // represents all the valid TypedArray types plus DataView. They all have
-    // ".buffer" as an instance of ArrayBuffer.
-    bytes = new Uint8Array(buffer.buffer);
-  } else {
-    // The only other valid argument here is that "buffer" is an ArrayBuffer.
-    // We also try to convert anything else passed to a Uint8Array, as this
-    // catches anything that's array-like. Native code would throw here.
-    bytes = new Uint8Array(buffer);
-  }
-
-  return decodeImpl(/** @type {!Uint8Array} */ (bytes));
-};
-
-export { FastTextEncoder as TextEncoder };
-export { FastTextDecoder as TextDecoder };
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 5a5574998..9fe0236df 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -10,7 +10,7 @@ importers:
       highlight.js: ^11.3.1
       moment: ^2.29.1
       peechy: 0.4.20
-      prettier: latest
+      prettier: ^2.4.1
       puppeteer: ^10.2.0
       react: ^17.0.2
       react-dom: ^17.0.2
@@ -19,13 +19,13 @@ importers:
       highlight.js: 11.3.1
       moment: 2.29.1
       peechy: 0.4.20
-      prettier: 2.4.1
       puppeteer: 10.4.0
       react: 17.0.2
       react-dom: 17.0.2_react@17.0.2
     devDependencies:
       '@types/node': 16.11.4
       '@types/puppeteer': 5.4.4
+      prettier: 2.4.1
 
   packages/bun-error:
     specifiers:
@@ -1835,7 +1835,7 @@ packages:
     resolution: {integrity: sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==}
     engines: {node: '>=10.13.0'}
     hasBin: true
-    dev: false
+    dev: true
 
   /pretty-format/3.8.0:
     resolution: {integrity: sha1-v77VbV6ad2ZF9LH/eqGjrE+jw4U=}
-- 
cgit v1.2.3


From c06e34c687187a528d0da39eddec71323b56e77a Mon Sep 17 00:00:00 2001
From: Jack Hanford <jackhanford@gmail.com>
Date: Mon, 22 Nov 2021 10:23:14 -0800
Subject: misc

---
 packages/bun-framework-next/renderDocument.tsx   | 24 +++++++++---------------
 packages/bun-framework-next/server-polyfills.tsx |  7 ++-----
 2 files changed, 11 insertions(+), 20 deletions(-)

(limited to 'packages/bun-framework-next/server-polyfills.tsx')

diff --git a/packages/bun-framework-next/renderDocument.tsx b/packages/bun-framework-next/renderDocument.tsx
index 5b4cab0ce..661bebdc0 100644
--- a/packages/bun-framework-next/renderDocument.tsx
+++ b/packages/bun-framework-next/renderDocument.tsx
@@ -1,4 +1,4 @@
-import * as App from "next/app";
+import App from "next/app";
 import { AmpStateContext } from "next/dist/shared/lib/amp-context";
 import { HeadManagerContext } from "next/dist/shared/lib/head-manager-context";
 import Loadable from "next/dist/shared/lib/loadable";
@@ -23,7 +23,9 @@ import * as NextDocument from "next/document";
 import * as ReactDOMServer from "react-dom/server.browser";
 import * as React from "react";
 import * as ReactIs from "react-is";
-import { BODY_RENDER_TARGET } from "next/constants";
+
+// This constant was removed from Next, Is it doing anything?
+const BODY_RENDER_TARGET = "__NEXT_BODY_RENDER_TARGET__";
 
 const dev = process.env.NODE_ENV === "development";
 
@@ -362,11 +364,8 @@ export async function render({
     pages["/_app"] = [];
   }
 
-  const AppComponent = AppComponent_ || App.default;
-  const Document =
-    (DocumentNamespace && DocumentNamespace.default) || NextDocument.default;
-  //   Document.Html.prototype.getScripts = getScripts;
-  // }
+  const AppComponent = AppComponent_ || App;
+  const Document = (DocumentNamespace as any)?.default || NextDocument.default;
 
   const callMiddleware = async (method: string, args: any[], props = false) => {
     let results: any = props ? {} : [];
@@ -422,7 +421,7 @@ export async function render({
   delete query.__nextLocale;
   delete query.__nextDefaultLocale;
 
-  const isSSG = !!getStaticProps;
+  // const isSSG = !!getStaticProps;
 
   const defaultAppGetInitialProps =
     App.getInitialProps === (App as any).origGetInitialProps;
@@ -518,7 +517,7 @@ export async function render({
       );
     },
     defaultGetInitialProps: async (
-      docCtx: DocumentContext
+      docCtx: NextDocument.DocumentContext
     ): Promise<DocumentInitialProps> => {
       const enhanceApp = (AppComp: any) => {
         return (props: any) => <AppComp {...props} />;
@@ -696,13 +695,7 @@ export async function render({
   const renderOpts = {
     params: route.params,
   };
-  // renderOpts.params = _params || params;
 
-  // parsedUrl.pathname = denormalizePagePath(parsedUrl.pathname!);
-  // renderOpts.resolvedUrl = formatUrl({
-  //   ...parsedUrl,
-  //   query: origQuery,
-  // });
   const docComponentsRendered: DocumentProps["docComponentsRendered"] = {};
 
   let html = renderDocument(Document, {
@@ -752,6 +745,7 @@ export async function render({
     nextExport: nextExport,
     useMaybeDeferContent,
   });
+  // __NEXT_BODY_RENDER_TARGET__
   const bodyRenderIdx = html.indexOf(BODY_RENDER_TARGET);
   html =
     html.substring(0, bodyRenderIdx) +
diff --git a/packages/bun-framework-next/server-polyfills.tsx b/packages/bun-framework-next/server-polyfills.tsx
index 887621978..57960e4fa 100644
--- a/packages/bun-framework-next/server-polyfills.tsx
+++ b/packages/bun-framework-next/server-polyfills.tsx
@@ -3,12 +3,9 @@ globalThis.global = globalThis;
 import { Buffer } from "buffer";
 import { URL } from "url-polyfill";
 import { TextEncoder, TextDecoder } from "fast-text-encoding";
-
-globalThis.Buffer = Buffer;
-
 import * as React from "react";
 
-var onlyChildPolyfill = React.Children.only;
+const onlyChildPolyfill = React.Children.only;
 
 React.Children.only = function (children) {
   if (
@@ -22,7 +19,7 @@ React.Children.only = function (children) {
   return onlyChildPolyfill(children);
 };
 
+globalThis.Buffer = Buffer;
 globalThis.URL = URL;
-
 globalThis.TextEncoder ||= TextEncoder;
 globalThis.TextDecoder ||= TextDecoder;
-- 
cgit v1.2.3


From 9ab9b01a640cd157634494b6b703d095897ac412 Mon Sep 17 00:00:00 2001
From: Jack Hanford <jackhanford@gmail.com>
Date: Tue, 23 Nov 2021 10:51:08 -0500
Subject: stop installing textencoder

---
 packages/bun-framework-next/package.json           |   1 -
 packages/bun-framework-next/server-polyfills.tsx   |   3 +-
 .../bun-framework-next/text-encoder-polyfill.js    | 306 +++++++++++++++++++++
 3 files changed, 308 insertions(+), 2 deletions(-)
 create mode 100644 packages/bun-framework-next/text-encoder-polyfill.js

(limited to 'packages/bun-framework-next/server-polyfills.tsx')

diff --git a/packages/bun-framework-next/package.json b/packages/bun-framework-next/package.json
index d715a8ba4..646b8e4af 100644
--- a/packages/bun-framework-next/package.json
+++ b/packages/bun-framework-next/package.json
@@ -11,7 +11,6 @@
   "author": "",
   "license": "MIT",
   "dependencies": {
-    "fast-text-encoding": "^1.0.3",
     "react-is": "^17.0.2",
     "url-polyfill": "^1.1.12"
   },
diff --git a/packages/bun-framework-next/server-polyfills.tsx b/packages/bun-framework-next/server-polyfills.tsx
index 57960e4fa..f0a2b5c3a 100644
--- a/packages/bun-framework-next/server-polyfills.tsx
+++ b/packages/bun-framework-next/server-polyfills.tsx
@@ -2,7 +2,7 @@ globalThis.global = globalThis;
 
 import { Buffer } from "buffer";
 import { URL } from "url-polyfill";
-import { TextEncoder, TextDecoder } from "fast-text-encoding";
+import { TextEncoder, TextDecoder } from "./text-encoder-polyfill";
 import * as React from "react";
 
 const onlyChildPolyfill = React.Children.only;
@@ -21,5 +21,6 @@ React.Children.only = function (children) {
 
 globalThis.Buffer = Buffer;
 globalThis.URL = URL;
+// @ts-expect-error encodeInto is missing in our polyfill
 globalThis.TextEncoder ||= TextEncoder;
 globalThis.TextDecoder ||= TextDecoder;
diff --git a/packages/bun-framework-next/text-encoder-polyfill.js b/packages/bun-framework-next/text-encoder-polyfill.js
new file mode 100644
index 000000000..01c7cbbe8
--- /dev/null
+++ b/packages/bun-framework-next/text-encoder-polyfill.js
@@ -0,0 +1,306 @@
+/*
+ * Copyright 2017 Sam Thorogood. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+/**
+ * @fileoverview Polyfill for TextEncoder and TextDecoder.
+ *
+ * You probably want `text.min.js`, and not this file directly.
+ */
+
+// used for FastTextDecoder
+const validUtfLabels = ["utf-8", "utf8", "unicode-1-1-utf-8"];
+
+/**
+ * @constructor
+ */
+function FastTextEncoder() {
+  // This does not accept an encoding, and always uses UTF-8:
+  //   https://www.w3.org/TR/encoding/#dom-textencoder
+}
+
+Object.defineProperty(FastTextEncoder.prototype, "encoding", {
+  value: "utf-8",
+});
+
+Object.defineProperty(FastTextEncoder.prototype, "encodeInto", {
+  value: "",
+});
+
+/**
+ * @param {string} string
+ * @param {{stream: boolean}=} options
+ * @return {!Uint8Array}
+ */
+FastTextEncoder.prototype["encode"] = function (
+  string,
+  options = { stream: false }
+) {
+  if (options.stream) {
+    throw new Error(`Failed to encode: the 'stream' option is unsupported.`);
+  }
+
+  let pos = 0;
+  const len = string.length;
+
+  let at = 0; // output position
+  let tlen = Math.max(32, len + (len >>> 1) + 7); // 1.5x size
+  let target = new Uint8Array((tlen >>> 3) << 3); // ... but at 8 byte offset
+
+  while (pos < len) {
+    let value = string.charCodeAt(pos++);
+    if (value >= 0xd800 && value <= 0xdbff) {
+      // high surrogate
+      if (pos < len) {
+        const extra = string.charCodeAt(pos);
+        if ((extra & 0xfc00) === 0xdc00) {
+          ++pos;
+          value = ((value & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;
+        }
+      }
+      if (value >= 0xd800 && value <= 0xdbff) {
+        continue; // drop lone surrogate
+      }
+    }
+
+    // expand the buffer if we couldn't write 4 bytes
+    if (at + 4 > target.length) {
+      tlen += 8; // minimum extra
+      tlen *= 1.0 + (pos / string.length) * 2; // take 2x the remaining
+      tlen = (tlen >>> 3) << 3; // 8 byte offset
+
+      const update = new Uint8Array(tlen);
+      update.set(target);
+      target = update;
+    }
+
+    if ((value & 0xffffff80) === 0) {
+      // 1-byte
+      target[at++] = value; // ASCII
+      continue;
+    } else if ((value & 0xfffff800) === 0) {
+      // 2-byte
+      target[at++] = ((value >>> 6) & 0x1f) | 0xc0;
+    } else if ((value & 0xffff0000) === 0) {
+      // 3-byte
+      target[at++] = ((value >>> 12) & 0x0f) | 0xe0;
+      target[at++] = ((value >>> 6) & 0x3f) | 0x80;
+    } else if ((value & 0xffe00000) === 0) {
+      // 4-byte
+      target[at++] = ((value >>> 18) & 0x07) | 0xf0;
+      target[at++] = ((value >>> 12) & 0x3f) | 0x80;
+      target[at++] = ((value >>> 6) & 0x3f) | 0x80;
+    } else {
+      continue; // out of range
+    }
+
+    target[at++] = (value & 0x3f) | 0x80;
+  }
+
+  // Use subarray if slice isn't supported (IE11). This will use more memory
+  // because the original array still exists.
+  return target.slice ? target.slice(0, at) : target.subarray(0, at);
+};
+
+/**
+ * @constructor
+ * @param {string=} utfLabel
+ * @param {{fatal: boolean}=} options
+ */
+function FastTextDecoder(utfLabel = "utf-8", options = { fatal: false }) {
+  if (validUtfLabels.indexOf(utfLabel.toLowerCase()) === -1) {
+    throw new RangeError(
+      `Failed to construct 'TextDecoder': The encoding label provided ('${utfLabel}') is invalid.`
+    );
+  }
+  if (options.fatal) {
+    throw new Error(
+      `Failed to construct 'TextDecoder': the 'fatal' option is unsupported.`
+    );
+  }
+}
+
+Object.defineProperty(FastTextDecoder.prototype, "encoding", {
+  value: "utf-8",
+});
+
+Object.defineProperty(FastTextDecoder.prototype, "fatal", { value: false });
+
+Object.defineProperty(FastTextDecoder.prototype, "ignoreBOM", {
+  value: false,
+});
+
+/**
+ * @param {!Uint8Array} bytes
+ * @return {string}
+ */
+function decodeBuffer(bytes) {
+  return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString(
+    "utf-8"
+  );
+}
+
+/**
+ * @param {!Uint8Array} bytes
+ * @return {string}
+ */
+function decodeSyncXHR(bytes) {
+  const b = new Blob([bytes], { type: "text/plain;charset=UTF-8" });
+  const u = URL.createObjectURL(b);
+
+  // This hack will fail in non-Edgium Edge because sync XHRs are disabled (and
+  // possibly in other places), so ensure there's a fallback call.
+  try {
+    const x = new XMLHttpRequest();
+    x.open("GET", u, false);
+    x.send();
+    return x.responseText;
+  } catch (e) {
+    return decodeFallback(bytes);
+  } finally {
+    URL.revokeObjectURL(u);
+  }
+}
+
+/**
+ * @param {!Uint8Array} bytes
+ * @return {string}
+ */
+function decodeFallback(bytes) {
+  let inputIndex = 0;
+
+  // Create a working buffer for UTF-16 code points, but don't generate one
+  // which is too large for small input sizes. UTF-8 to UCS-16 conversion is
+  // going to be at most 1:1, if all code points are ASCII. The other extreme
+  // is 4-byte UTF-8, which results in two UCS-16 points, but this is still 50%
+  // fewer entries in the output.
+  const pendingSize = Math.min(256 * 256, bytes.length + 1);
+  const pending = new Uint16Array(pendingSize);
+  const chunks = [];
+  let pendingIndex = 0;
+
+  for (;;) {
+    const more = inputIndex < bytes.length;
+
+    // If there's no more data or there'd be no room for two UTF-16 values,
+    // create a chunk. This isn't done at the end by simply slicing the data
+    // into equal sized chunks as we might hit a surrogate pair.
+    if (!more || pendingIndex >= pendingSize - 1) {
+      // nb. .apply and friends are *really slow*. Low-hanging fruit is to
+      // expand this to literally pass pending[0], pending[1], ... etc, but
+      // the output code expands pretty fast in this case.
+      chunks.push(
+        String.fromCharCode.apply(null, pending.subarray(0, pendingIndex))
+      );
+
+      if (!more) {
+        return chunks.join("");
+      }
+
+      // Move the buffer forward and create another chunk.
+      bytes = bytes.subarray(inputIndex);
+      inputIndex = 0;
+      pendingIndex = 0;
+    }
+
+    // The native TextDecoder will generate "REPLACEMENT CHARACTER" where the
+    // input data is invalid. Here, we blindly parse the data even if it's
+    // wrong: e.g., if a 3-byte sequence doesn't have two valid continuations.
+
+    const byte1 = bytes[inputIndex++];
+    if ((byte1 & 0x80) === 0) {
+      // 1-byte or null
+      pending[pendingIndex++] = byte1;
+    } else if ((byte1 & 0xe0) === 0xc0) {
+      // 2-byte
+      const byte2 = bytes[inputIndex++] & 0x3f;
+      pending[pendingIndex++] = ((byte1 & 0x1f) << 6) | byte2;
+    } else if ((byte1 & 0xf0) === 0xe0) {
+      // 3-byte
+      const byte2 = bytes[inputIndex++] & 0x3f;
+      const byte3 = bytes[inputIndex++] & 0x3f;
+      pending[pendingIndex++] = ((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3;
+    } else if ((byte1 & 0xf8) === 0xf0) {
+      // 4-byte
+      const byte2 = bytes[inputIndex++] & 0x3f;
+      const byte3 = bytes[inputIndex++] & 0x3f;
+      const byte4 = bytes[inputIndex++] & 0x3f;
+
+      // this can be > 0xffff, so possibly generate surrogates
+      let codepoint =
+        ((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;
+      if (codepoint > 0xffff) {
+        // codepoint &= ~0x10000;
+        codepoint -= 0x10000;
+        pending[pendingIndex++] = ((codepoint >>> 10) & 0x3ff) | 0xd800;
+        codepoint = 0xdc00 | (codepoint & 0x3ff);
+      }
+      pending[pendingIndex++] = codepoint;
+    } else {
+      // invalid initial byte
+    }
+  }
+}
+
+// Decoding a string is pretty slow, but use alternative options where possible.
+let decodeImpl = decodeFallback;
+if (typeof Buffer === "function" && Buffer.from) {
+  // Buffer.from was added in Node v5.10.0 (2015-11-17).
+  decodeImpl = decodeBuffer;
+} else if (
+  typeof Blob === "function" &&
+  typeof URL === "function" &&
+  typeof URL.createObjectURL === "function"
+) {
+  // Blob and URL.createObjectURL are available from IE10, Safari 6, Chrome 19
+  // (all released in 2012), Firefox 19 (2013), ...
+  decodeImpl = decodeSyncXHR;
+}
+
+/**
+ * @param {(!ArrayBuffer|!ArrayBufferView)} buffer
+ * @param {{stream: boolean}=} options
+ * @return {string}
+ */
+FastTextDecoder.prototype["decode"] = function (
+  buffer,
+  options = { stream: false }
+) {
+  if (options["stream"]) {
+    throw new Error(`Failed to decode: the 'stream' option is unsupported.`);
+  }
+
+  let bytes;
+
+  if (buffer instanceof Uint8Array) {
+    // Accept Uint8Array instances as-is.
+    bytes = buffer;
+  } else if (buffer.buffer instanceof ArrayBuffer) {
+    // Look for ArrayBufferView, which isn't a real type, but basically
+    // represents all the valid TypedArray types plus DataView. They all have
+    // ".buffer" as an instance of ArrayBuffer.
+    bytes = new Uint8Array(buffer.buffer);
+  } else {
+    // The only other valid argument here is that "buffer" is an ArrayBuffer.
+    // We also try to convert anything else passed to a Uint8Array, as this
+    // catches anything that's array-like. Native code would throw here.
+    bytes = new Uint8Array(buffer);
+  }
+
+  return decodeImpl(/** @type {!Uint8Array} */ (bytes));
+};
+
+export { FastTextEncoder as TextEncoder };
+export { FastTextDecoder as TextDecoder };
-- 
cgit v1.2.3

