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

feat: rename satisfies to filter, add docs #1249

Merged
merged 62 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
1ccadc0
doc
ssalbdivad Jan 5, 2025
7708ab2
fixo
ssalbdivad Jan 5, 2025
a190fdd
continuuu
ssalbdivad Jan 5, 2025
a01e797
continuuue
ssalbdivad Jan 5, 2025
6bd1c6e
continu
ssalbdivad Jan 5, 2025
c399c83
ok
ssalbdivad Jan 5, 2025
8713609
dum doc
ssalbdivad Jan 5, 2025
0dd00be
self-cook
ssalbdivad Jan 5, 2025
e364ecc
up
ssalbdivad Jan 5, 2025
624c721
more
ssalbdivad Jan 5, 2025
c20026e
actually FIXO
ssalbdivad Jan 5, 2025
e7e5be2
big saver
ssalbdivad Jan 5, 2025
bfac85a
wow so fixo
ssalbdivad Jan 5, 2025
267b91d
huh ok
ssalbdivad Jan 5, 2025
01cc193
wow bad
ssalbdivad Jan 5, 2025
7700bd3
why docgen again
ssalbdivad Jan 5, 2025
7d5767b
up
ssalbdivad Jan 5, 2025
e6bfcc9
fixo generator
ssalbdivad Jan 5, 2025
e8e7691
gigas
ssalbdivad Jan 5, 2025
5ec7bf6
bork
ssalbdivad Jan 5, 2025
5fb067b
hmm ok
ssalbdivad Jan 5, 2025
2f65ee2
ok
ssalbdivad Jan 5, 2025
23d7e6b
ok
ssalbdivad Jan 5, 2025
91e18aa
blorf docs blorf
ssalbdivad Jan 5, 2025
98d3e67
add dumb horizon comment
ssalbdivad Jan 5, 2025
887f3b5
make the dumb comment dumber
ssalbdivad Jan 5, 2025
33809b1
ayy big continuue
ssalbdivad Jan 5, 2025
581387d
some predicate cleanup
ssalbdivad Jan 6, 2025
bb429d9
group some json schema types
ssalbdivad Jan 6, 2025
f116ab6
UnjsonifiableError
ssalbdivad Jan 6, 2025
532b735
work on donk
ssalbdivad Jan 6, 2025
895776e
fix typelevel jsdoc gen
ssalbdivad Jan 7, 2025
2d5fdd0
restore buildreo
ssalbdivad Jan 7, 2025
5ce55ff
doc doc doc
ssalbdivad Jan 7, 2025
7f92916
flatMorph groups
ssalbdivad Jan 7, 2025
3f0ec5c
initial jsdoc build
ssalbdivad Jan 7, 2025
9e9f47c
continuu
ssalbdivad Jan 7, 2025
f8c6a66
split
ssalbdivad Jan 7, 2025
14275db
fixo
ssalbdivad Jan 7, 2025
64a0fbc
moar
ssalbdivad Jan 7, 2025
d83a268
big ok
ssalbdivad Jan 7, 2025
d9b331b
add localfriendlyurl
ssalbdivad Jan 7, 2025
674a0cf
fix local links
ssalbdivad Jan 7, 2025
770a252
improve describe
ssalbdivad Jan 7, 2025
fe2d14b
big big
ssalbdivad Jan 7, 2025
20dca68
best better bigas
ssalbdivad Jan 7, 2025
917b8ed
moar
ssalbdivad Jan 7, 2025
aa74819
big descriptions
ssalbdivad Jan 7, 2025
5526a3b
moar
ssalbdivad Jan 7, 2025
e6c1d6d
bigas more gen
ssalbdivad Jan 7, 2025
6e078e0
tryharding
ssalbdivad Jan 8, 2025
2faa2fa
hardly trying
ssalbdivad Jan 8, 2025
5c58c96
actual tabling
ssalbdivad Jan 8, 2025
7c7d11f
more
ssalbdivad Jan 8, 2025
1137071
big improve
ssalbdivad Jan 8, 2025
b023256
big progress
ssalbdivad Jan 8, 2025
6d1fa9e
try
ssalbdivad Jan 8, 2025
7d75c71
good good
ssalbdivad Jan 8, 2025
e86c224
noice
ssalbdivad Jan 8, 2025
0eb9ed7
fix tests
ssalbdivad Jan 8, 2025
d29bbfd
fix escape character serialization
ssalbdivad Jan 8, 2025
5d0c749
fix type
ssalbdivad Jan 9, 2025
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
117 changes: 76 additions & 41 deletions ark/attest/cache/ts.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { fromCwd, type SourcePosition } from "@ark/fs"
import { printable, throwInternalError, type dict } from "@ark/util"
import { printable, throwError, throwInternalError, type dict } from "@ark/util"
import * as tsvfs from "@typescript/vfs"
import { readFileSync } from "node:fs"
import { dirname, join } from "node:path"
Expand Down Expand Up @@ -34,7 +34,7 @@ export class TsServer {

const system = tsvfs.createFSBackedSystem(
tsLibPaths.defaultMapFromNodeModules,
dirname(this.tsConfigInfo.path),
this.tsConfigInfo.path ? dirname(this.tsConfigInfo.path) : fromCwd(),
ts
)

Expand Down Expand Up @@ -105,64 +105,99 @@ export const getAbsolutePosition = (
}

export type TsconfigInfo = {
path: string
path: string | undefined
parsed: ts.ParsedCommandLine
}

export const getTsConfigInfoOrThrow = (): TsconfigInfo => {
const config = getConfig()
const tsconfig = config.tsconfig
const configFilePath =
tsconfig ?? ts.findConfigFile(fromCwd(), ts.sys.fileExists, "tsconfig.json")
if (!configFilePath) {
throw new Error(
`File ${tsconfig ?? join(fromCwd(), "tsconfig.json")} must exist`
)

let instantiatedConfig: ts.ParsedCommandLine | undefined
let configFilePath: string | undefined

if (tsconfig !== null) {
configFilePath =
tsconfig ??
ts.findConfigFile(fromCwd(), ts.sys.fileExists, "tsconfig.json")
if (configFilePath)
instantiatedConfig = instantiateTsconfigFromPath(configFilePath)
}

const configFileText = readFileSync(configFilePath).toString()
const result = ts.parseConfigFileTextToJson(configFilePath, configFileText)
if (result.error) {
throw new Error(
ts.formatDiagnostics([result.error], {
getCanonicalFileName: fileName => fileName,
getCurrentDirectory: process.cwd,
getNewLine: () => ts.sys.newLine
})
)
instantiatedConfig ??= instantiateNoFileConfig()

return {
path: configFilePath,
parsed: instantiatedConfig
}
}

type RawTsConfigJson = dict & { compilerOptions: ts.CompilerOptions }

const configJson: dict & { compilerOptions: ts.CompilerOptions } =
result.config
type InstantiatedTsConfigJson = ts.ParsedCommandLine

configJson.compilerOptions = Object.assign(
configJson.compilerOptions ?? {},
config.compilerOptions
const instantiateNoFileConfig = (): InstantiatedTsConfigJson => {
const arkConfig = getConfig()

const instantiatedConfig = ts.parseJsonConfigFileContent(
{
compilerOptions: arkConfig.compilerOptions
},
ts.sys,
fromCwd()
)
const configParseResult = ts.parseJsonConfigFileContent(
configJson,

if (instantiatedConfig.errors.length > 0)
throwConfigInstantiationError(instantiatedConfig)

return instantiatedConfig
}

const instantiateTsconfigFromPath = (
path: string
): InstantiatedTsConfigJson => {
const arkConfig = getConfig()
const configFileText = readFileSync(path).toString()
const result = ts.parseConfigFileTextToJson(path, configFileText)
if (result.error) throwConfigParseError(result.error)

const rawConfig: RawTsConfigJson = result.config

rawConfig.compilerOptions = Object.assign(
rawConfig.compilerOptions ?? {},
arkConfig.compilerOptions
)

const instantiatedConfig = ts.parseJsonConfigFileContent(
rawConfig,
ts.sys,
dirname(configFilePath),
dirname(path),
{},
configFilePath
path
)

if (configParseResult.errors.length > 0) {
throw new Error(
ts.formatDiagnostics(configParseResult.errors, {
getCanonicalFileName: fileName => fileName,
getCurrentDirectory: process.cwd,
getNewLine: () => ts.sys.newLine
})
)
}
if (instantiatedConfig.errors.length > 0)
throwConfigInstantiationError(instantiatedConfig)

return {
path: configFilePath,
parsed: configParseResult
}
return instantiatedConfig
}

const defaultDiagnosticHost: ts.FormatDiagnosticsHost = {
getCanonicalFileName: fileName => fileName,
getCurrentDirectory: process.cwd,
getNewLine: () => ts.sys.newLine
}

const throwConfigParseError = (error: ts.Diagnostic) =>
throwError(ts.formatDiagnostics([error], defaultDiagnosticHost))

const throwConfigInstantiationError = (
instantiatedConfig: InstantiatedTsConfigJson
): never =>
throwError(
ts.formatDiagnostics(instantiatedConfig.errors, defaultDiagnosticHost)
)

type TsLibFiles = {
defaultMapFromNodeModules: Map<string, string>
resolvedPaths: string[]
Expand Down
2 changes: 2 additions & 0 deletions ark/attest/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ const getParamValue = (param: keyof AttestConfig) => {

if (raw === "false") return false

if (raw === "null") return null

if (param === "benchPercentThreshold")
return tryParseNumber(raw, { errorOnFail: true })

Expand Down
2 changes: 1 addition & 1 deletion ark/attest/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ark/attest",
"version": "0.36.0",
"version": "0.37.0",
"license": "MIT",
"author": {
"name": "David Blass",
Expand Down
4 changes: 1 addition & 3 deletions ark/attest/tsVersioning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ import ts from "typescript"
*
* Throws an error if any version fails when the associated function is executed.
*
* @param {TsVersionData[]} versions The set of versions for which to exceute the function
* @param {function} fn - The function to execute for each TypeScript version.
* Should spawn a new process so the new symlinked version can be loaded.
* fn should spawn a new process so the new symlinked version can be loaded.
*/
export const forTypeScriptVersions = (
versions: TsVersionData[],
Expand Down
102 changes: 102 additions & 0 deletions ark/docs/components/ApiTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import type { JSX } from "react"
import type { ApiGroup, ParsedJsDocPart } from "../../repo/jsdocGen.ts"
import { apiDocsByGroup } from "./apiData.ts"
import { CodeBlock } from "./CodeBlock.tsx"
import { LocalFriendlyUrl } from "./LocalFriendlyUrl.tsx"

export type ApiTableProps = {
group: ApiGroup
rows: JSX.Element[]
}

export const ApiTable = ({ group }: ApiTableProps) => (
<>
<h2>{group}</h2>
<div className="w-full overflow-x-auto">
<table className="w-full table-fixed border-collapse">
<colgroup>
<col className="w-28" />
<col className="w-1/4" />
<col className="w-full" />
</colgroup>
<ApiTableHeader />
<tbody>
{apiDocsByGroup[group].map(props => (
<ApiTableRow key={props.name} {...props} />
))}
</tbody>
</table>
</div>
</>
)

const ApiTableHeader = () => (
<thead>
<tr>
<th className="p-2 text-left align-top whitespace-nowrap w-auto min-w-[100px]">
Name
</th>
<th className="p-2 text-left align-top min-w-[200px]">Summary</th>
<th className="p-2 text-left align-top">Example</th>
</tr>
</thead>
)

interface ApiTableRowProps {
name: string
summary: ParsedJsDocPart[]
example?: string
notes: ParsedJsDocPart[][]
}

const ApiTableRow = ({ name, summary, example, notes }: ApiTableRowProps) => (
<tr key={name}>
<td className="p-2 align-top whitespace-nowrap w-auto">{name}</td>
<td className="p-2 align-top">{JsDocParts(summary)}</td>
<td className="p-2 align-top">
{notes.map((note, i) => (
<div key={i}>{JsDocParts(note)} </div>
))}
<ApiExample>{example}</ApiExample>
</td>
</tr>
)

const JsDocParts = (parts: readonly ParsedJsDocPart[]) =>
parts.map((part, i) => (
<span key={i} style={{ marginRight: "0.25em" }}>
{part.kind === "link" ?
<LocalFriendlyUrl url={part.url} key={i}>
{part.value}
</LocalFriendlyUrl>
: part.kind === "reference" ?
<a href={`#${part.value}`} key={i}>
{part.value}
</a>
: part.kind === "tag" ?
<p key={i}>
{part.name} {JsDocParts(part.value)}
</p>
: <p
style={{ display: "inline" }}
key={i}
dangerouslySetInnerHTML={{
__html: part.value
.replace(/(\*\*|__)([^*_]+)\1/g, "<strong>$2</strong>")
.replace(/(\*|_)([^*_]+)\1/g, "<em>$2</em>")
}}
/>
}
</span>
))

interface ApiExampleProps {
children: string | undefined
}

const ApiExample = ({ children }: ApiExampleProps) =>
children && (
<CodeBlock style={{ margin: 0 }} decorators={["@noErrors"]}>
{children}
</CodeBlock>
)
16 changes: 12 additions & 4 deletions ark/docs/components/CodeBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ export type CodeBlockProps = {
style?: React.CSSProperties
className?: string
includesCompletions?: boolean
decorators?: CodeBlockDecorator[]
} & propwiseXor<{ children: string }, { fromFile: SnippetId }>

export type CodeBlockDecorator = "@noErrors"

// preload languages for shiki
// https://github.com/fuma-nama/fumadocs/issues/1095
const highlighter = await getSingletonHighlighter({
Expand Down Expand Up @@ -51,19 +54,24 @@ export const CodeBlock: React.FC<CodeBlockProps> = ({
fromFile,
style,
className,
includesCompletions
includesCompletions,
decorators
}) => {
children ??= snippetContentsById[fromFile!]
let src = children ?? snippetContentsById[fromFile!]

if (!children) {
if (!src) {
throwInternalError(
fromFile ?
`Specified snippet '${fromFile}' does not have a corresponding file`
: `CodeBlock requires either a fromFile prop or a string child representing its text contents`
)
}

const highlighted = highlight(lang, children)
decorators?.forEach(d => {
if (!src.includes(d)) src = `// ${d}\n${src}`
})

const highlighted = highlight(lang, src)

return (
<FumaCodeBlock
Expand Down
27 changes: 27 additions & 0 deletions ark/docs/components/LocalFriendlyUrl.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"use client"
import { useEffect, useState } from "react"

export interface LocalFriendlyUrlProps {
children: string
url: string
key?: string | number | undefined
}

export const LocalFriendlyUrl = (props: LocalFriendlyUrlProps) => {
const [locallyAccessibleUrl, setLocallyAccessibleUrl] = useState(props.url)

if (process.env.NODE_ENV === "development") {
useEffect(() => {
const devFriendlyUrl = new URL(props.url)
devFriendlyUrl.protocol = "http:"
devFriendlyUrl.host = window.location.host
setLocallyAccessibleUrl(devFriendlyUrl.toString())
}, [props.url])
}

return (
<a href={locallyAccessibleUrl} key={props.key}>
{props.children}
</a>
)
}
Loading
Loading