Let's assume we wanna show a tree like this:
ServerRoot # RSC
html
body
MyLayout # RSC
main
"Hello"
export type Thenable<T> = | |
| PendingThenable<T> | |
| FulfilledThenable<T> | |
| RejectedThenable<T> | |
type PendingThenable<T> = Promise<T> & { status: 'pending' } | |
type FulfilledThenable<T> = Promise<T> & { status: 'fulfilled'; value: T } | |
type RejectedThenable<T> = Promise<T> & { status: 'rejected'; reason: unknown } | |
export function trackThenableState<T>(promise: Promise<T>): Thenable<T> { |
/** A `try-catch-finally` that works for both sync and async callbacks. */ | |
export function tryCatch<T>( | |
cb: () => T | Promise<T>, | |
options: { catch?: (error: unknown) => T; finally?: () => void } | |
): T { | |
const { catch: onCatch, finally: onFinally } = options | |
let isAsync = false | |
try { | |
const result = cb() |
// https://pico.bsky.mom/ | |
(async () => { | |
// sine | |
const lines = 24 | |
function sine(t) { | |
const w = 12; | |
const arr = new Array(12).fill('.'); | |
const ix = Math.floor(((Math.cos(t * 0.6) + 1) / 2) * w); | |
arr[ix] = '#'; |
type Replace< | |
Obj extends Record<string, any>, | |
Field extends keyof Obj, | |
NewType, | |
> = Reveal< | |
{ [Key in keyof Obj]: Key extends Field ? NewType : Obj[Key] } | |
> | |
type Reveal<Obj extends Record<string, any>> = { | |
[K in keyof Obj]: Obj[K] |
export type Thenable<T> = PendingThenable<T> | FulfilledThenable<T> | RejectedThenable<T> | |
export type PendingThenable<T> = Promise<T> & { status: 'pending' } | |
export type FulfilledThenable<T> = Promise<T> & { status: 'fulfilled', value: T } | |
export type RejectedThenable<T> = Promise<T> & { status: 'rejected', reason: unknown } | |
export function trackThenableState<T>(promise: Promise<T>): Thenable<T> { | |
const thenable = promise as Thenable<T>; | |
if ("status" in thenable && typeof thenable.status === "string") { |
/// <reference types="react/canary" /> | |
import React, { cache } from "react"; | |
type Options = { passthrough?: boolean }; | |
const OPTIONS_DEFAULT: Options = { passthrough: false }; | |
type RecordOrTupleArg = Record<string, any> | any[] | |
export function cacheValue<TObj extends RecordOrTupleArg>( | |
v: RecordOrTupleArg, |
(() => { | |
const env = { self: {} }; | |
const chunks = Array.from(document.body.querySelectorAll("script")) | |
.filter((s) => !!s.textContent && s.textContent.includes("self.__next_f")) | |
.forEach((s) => new Function("self", s.textContent)(env.self)); | |
return env.self.__next_f | |
.filter((c) => c[0] === 1) | |
.map((c) => c[1]) | |
.join(""); | |
})(); |
diff --git a/node_modules/next/dist/build/webpack/loaders/next-flight-loader/index.js b/node_modules/next/dist/build/webpack/loaders/next-flight-loader/index.js | |
index 59e02e7..0bf857b 100644 | |
--- a/node_modules/next/dist/build/webpack/loaders/next-flight-loader/index.js | |
+++ b/node_modules/next/dist/build/webpack/loaders/next-flight-loader/index.js | |
@@ -43,6 +43,7 @@ function transformSource(source, sourceMap) { | |
// and we shouldn't error for that. In the future we might want to find a way | |
// to only throw when it's used. | |
if (!this.resourcePath.includes("node_modules")) { | |
+ console.log('uh oh:', this._module.resourceResolveData.context.issuer, '->', this._module.resource) | |
this.callback(new Error(`You're importing a Client Component ("use client") from another Client Component imported Server Action file ("use server"). This is not allowed due to cyclic module graph between Server and Client.\nYou can work around it by defining and passing this |
// @ts-check | |
/* eslint-disable @typescript-eslint/no-var-requires */ | |
const { declare: declarePlugin } = require("@babel/helper-plugin-utils"); | |
const { addNamed } = require("@babel/helper-module-imports"); | |
const crypto = require("node:crypto"); | |
const { pathToFileURL } = require("node:url"); | |
// TODO: handle inline actions calling each other...? sounds tricky... |
Let's assume we wanna show a tree like this:
ServerRoot # RSC
html
body
MyLayout # RSC
main
"Hello"