mirror of
https://github.com/clockworklabs/SpacetimeDB.git
synced 2026-05-06 07:26:43 -04:00
Added a script to check the validity of docs links and a .github action (#122)
* Added a script to check the validity of docs links and a .github action * Removed erroneous thing * Switched the action trigger * Added workflow to ensure that the nav.ts has been built to nav.js * typo * Build nav.ts * typo thing * Fixed script issue * Fix * Fixed a few links * Added relative link resolution and fixed the broken links * now checking fragments * Now checking fragments properly and publishing some stats * Forgot exit code * Fix broken links Well, in at least some cases, just remove broken links. - The BSATN ref contained links to type defns, but didn't have type defns. Replace the links with plain text. - HTTP database links for recovery-code related routes were getting mangled in some way I couldn't figure out, so the links weren't working despite their targets clearly existing. Conveniently, those routes have been removed, so remove the links and the corresponding sections. - The JSON doc (erroneously called "SATN") contained typos, spelling "producttype" as "productype". - C# SDK ref had links to a section on the `Address` type, but no such section. Replace the links with plain text. - Rust SDK ref had a link getting mangled in a way I couldn't figure out. Simplify the section title so that the anchor name is predictable. - TypeSciprt SDK ref used camelCase names in anchor links, but we downcase all section titles to create anchor names. Also slap a section in README.md which says how to run the checker locally. --------- Co-authored-by: Phoebe Goldman <phoebe@goldman-tribe.org>
This commit is contained in:
+26
@@ -0,0 +1,26 @@
|
||||
name: Check Link Validity in Documentation
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
check-links:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '16' # or the version of Node.js you're using
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
npm install
|
||||
|
||||
- name: Run link check
|
||||
run: |
|
||||
npm run check-links
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
name: Validate nav.ts Matches nav.js
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
validate-build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '16'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
npm install
|
||||
|
||||
- name: Backup existing nav.js
|
||||
run: |
|
||||
mv docs/nav.js docs/nav.js.original
|
||||
|
||||
- name: Build nav.ts
|
||||
run: |
|
||||
npm run build
|
||||
|
||||
- name: Compare generated nav.js with original nav.js
|
||||
run: |
|
||||
diff -q docs/nav.js docs/nav.js.original || (echo "Generated nav.js differs from committed version. Run 'npm run build' and commit the updated file." && exit 1)
|
||||
|
||||
- name: Restore original nav.js
|
||||
if: success() || failure()
|
||||
run: |
|
||||
mv docs/nav.js.original docs/nav.js
|
||||
@@ -32,6 +32,10 @@ git push -u origin a-branch-name-that-describes-my-change
|
||||
|
||||
> NOTE! If you make a change to `nav.ts` you will have to run `npm run build` to generate a new `docs/nav.js` file.
|
||||
|
||||
### Checking Links
|
||||
|
||||
We have a CI job which validates internal links. You can run it locally with `npm run check-links`. This will print any internal links (i.e. links to other docs pages) whose targets do not exist, including fragment links (i.e. `#`-ey links to anchors).
|
||||
|
||||
## License
|
||||
|
||||
This documentation repository is licensed under Apache 2.0. See LICENSE.txt for more details.
|
||||
|
||||
+13
-19
@@ -24,12 +24,12 @@ To do this, we use inductive definitions, and define the following notation:
|
||||
|
||||
### At a glance
|
||||
|
||||
| Type | Description |
|
||||
| ---------------- | ---------------------------------------------------------------- |
|
||||
| `AlgebraicValue` | A value whose type may be any [`AlgebraicType`](#algebraictype). |
|
||||
| `SumValue` | A value whose type is a [`SumType`](#sumtype). |
|
||||
| `ProductValue` | A value whose type is a [`ProductType`](#producttype). |
|
||||
| `BuiltinValue` | A value whose type is a [`BuiltinType`](#builtintype). |
|
||||
| Type | Description |
|
||||
|-------------------------------------|-----------------------------------------------------------------------|
|
||||
| [`AlgebraicValue`](#algebraicvalue) | A value of any type. |
|
||||
| [`SumValue`](#sumvalue) | A value of a sum type, i.e. an enum or tagged union. |
|
||||
| [`ProductValue`](#productvalue) | A value of a product type, i.e. a struct or tuple. |
|
||||
| [`BuiltinValue`](#builtinvalue) | A value of a builtin type, including numbers, booleans and sequences. |
|
||||
|
||||
### `AlgebraicValue`
|
||||
|
||||
@@ -41,17 +41,17 @@ bsatn(AlgebraicValue) = bsatn(SumValue) | bsatn(ProductValue) | bsatn(BuiltinVal
|
||||
|
||||
### `SumValue`
|
||||
|
||||
An instance of a [`SumType`](#sumtype).
|
||||
An instance of a sum type, i.e. an enum or tagged union.
|
||||
`SumValue`s are binary-encoded as `bsatn(tag) ++ bsatn(variant_data)`
|
||||
where `tag: u8` is an index into the [`SumType.variants`](#sumtype)
|
||||
array of the value's [`SumType`](#sumtype),
|
||||
where `tag: u8` is an index into the `SumType.variants`
|
||||
array of the value's `SumType`,
|
||||
and where `variant_data` is the data of the variant.
|
||||
For variants holding no data, i.e., of some zero sized type,
|
||||
`bsatn(variant_data) = []`.
|
||||
|
||||
### `ProductValue`
|
||||
|
||||
An instance of a [`ProductType`](#producttype).
|
||||
An instance of a product type, i.e. a struct or tuple.
|
||||
`ProductValue`s are binary encoded as:
|
||||
|
||||
```fsharp
|
||||
@@ -62,7 +62,8 @@ Field names are not encoded.
|
||||
|
||||
### `BuiltinValue`
|
||||
|
||||
An instance of a [`BuiltinType`](#builtintype).
|
||||
An instance of a buil-in type.
|
||||
Built-in types include booleans, integers, floats, strings and arrays.
|
||||
The BSATN encoding of `BuiltinValue`s defers to the encoding of each variant:
|
||||
|
||||
```fsharp
|
||||
@@ -73,7 +74,6 @@ bsatn(BuiltinValue)
|
||||
| bsatn(F32) | bsatn(F64)
|
||||
| bsatn(String)
|
||||
| bsatn(Array)
|
||||
| bsatn(Map)
|
||||
|
||||
bsatn(Bool(b)) = bsatn(b as u8)
|
||||
bsatn(U8(x)) = [x]
|
||||
@@ -91,10 +91,6 @@ bsatn(F64(x: f64)) = bsatn(f64_to_raw_bits(x)) // lossless conversion
|
||||
bsatn(String(s)) = bsatn(len(s) as u32) ++ bsatn(bytes(s))
|
||||
bsatn(Array(a)) = bsatn(len(a) as u32)
|
||||
++ bsatn(normalize(a)_0) ++ .. ++ bsatn(normalize(a)_n)
|
||||
bsatn(Map(map)) = bsatn(len(m) as u32)
|
||||
++ bsatn(key(map_0)) ++ bsatn(value(map_0))
|
||||
..
|
||||
++ bsatn(key(map_n)) ++ bsatn(value(map_n))
|
||||
```
|
||||
|
||||
Where
|
||||
@@ -102,14 +98,12 @@ Where
|
||||
- `f32_to_raw_bits(x)` is the raw transmute of `x: f32` to `u32`
|
||||
- `f64_to_raw_bits(x)` is the raw transmute of `x: f64` to `u64`
|
||||
- `normalize(a)` for `a: ArrayValue` converts `a` to a list of `AlgebraicValue`s
|
||||
- `key(map_i)` extracts the key of the `i`th entry of `map`
|
||||
- `value(map_i)` extracts the value of the `i`th entry of `map`
|
||||
|
||||
## Types
|
||||
|
||||
All SATS types are BSATN-encoded by converting them to an `AlgebraicValue`,
|
||||
then BSATN-encoding that meta-value.
|
||||
|
||||
See [the SATN JSON Format](/docs/satn-reference-json-format)
|
||||
See [the SATN JSON Format](/docs/satn)
|
||||
for more details of the conversion to meta values.
|
||||
Note that these meta values are converted to BSATN and _not JSON_.
|
||||
|
||||
@@ -11,8 +11,6 @@ The HTTP endpoints in `/database` allow clients to interact with Spacetime datab
|
||||
| [`/database/set_name GET`](#databaseset_name-get) | Set a database's name, given its address. |
|
||||
| [`/database/ping GET`](#databaseping-get) | No-op. Used to determine whether a client can connect. |
|
||||
| [`/database/register_tld GET`](#databaseregister_tld-get) | Register a top-level domain. |
|
||||
| [`/database/request_recovery_code GET`](#databaserequest_recovery_code-get) | Request a recovery code to the email associated with an identity. |
|
||||
| [`/database/confirm_recovery_code GET`](#databaseconfirm_recovery_code-get) | Recover a login token from a recovery code. |
|
||||
| [`/database/publish POST`](#databasepublish-post) | Publish a database given its module code. |
|
||||
| [`/database/delete/:address POST`](#databasedeleteaddress-post) | Delete a database. |
|
||||
| [`/database/subscribe/:name_or_address GET`](#databasesubscribename_or_address-get) | Begin a [WebSocket connection](/docs/ws). |
|
||||
@@ -175,43 +173,6 @@ If the domain is already registered to another identity, returns JSON in the for
|
||||
} }
|
||||
```
|
||||
|
||||
## `/database/request_recovery_code GET`
|
||||
|
||||
Request a recovery code or link via email, in order to recover the token associated with an identity.
|
||||
|
||||
Accessible through the CLI as `spacetime identity recover <email> <identity>`.
|
||||
|
||||
#### Query Parameters
|
||||
|
||||
| Name | Value |
|
||||
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `identity` | The identity whose token should be recovered. |
|
||||
| `email` | The email to send the recovery code or link to. This email must be associated with the identity, either during creation via [`/identity`](/docs/http/identity#identity-post) or afterwards via [`/identity/:identity/set-email`](/docs/http/identity#identityidentityset_email-post). |
|
||||
| `link` | A boolean; whether to send a clickable link rather than a recovery code. |
|
||||
|
||||
## `/database/confirm_recovery_code GET`
|
||||
|
||||
Confirm a recovery code received via email following a [`/database/request_recovery_code GET`](#-database-request_recovery_code-get) request, and retrieve the identity's token.
|
||||
|
||||
Accessible through the CLI as `spacetime identity recover <email> <identity>`.
|
||||
|
||||
#### Query Parameters
|
||||
|
||||
| Name | Value |
|
||||
| ---------- | --------------------------------------------- |
|
||||
| `identity` | The identity whose token should be recovered. |
|
||||
| `email` | The email which received the recovery code. |
|
||||
| `code` | The recovery code received via email. |
|
||||
|
||||
On success, returns JSON in the form:
|
||||
|
||||
```typescript
|
||||
{
|
||||
"identity": string,
|
||||
"token": string
|
||||
}
|
||||
```
|
||||
|
||||
## `/database/publish POST`
|
||||
|
||||
Publish a database.
|
||||
|
||||
@@ -312,6 +312,6 @@ spacetime sql <module-name> "SELECT * FROM Message"
|
||||
|
||||
## What's next?
|
||||
|
||||
You've just set up your first database in SpacetimeDB! The next step would be to create a client module that interacts with this module. You can use any of SpacetimDB's supported client languages to do this. Take a look at the quick start guide for your client language of choice: [Rust](/docs/languages/rust/rust-sdk-quickstart-guide), [C#](/docs/languages/csharp/csharp-sdk-quickstart-guide), or [TypeScript](/docs/languages/typescript/typescript-sdk-quickstart-guide).
|
||||
You've just set up your first database in SpacetimeDB! The next step would be to create a client module that interacts with this module. You can use any of SpacetimDB's supported client languages to do this. Take a look at the quick start guide for your client language of choice: [Rust](/docs/sdks/rust/quickstart), [C#](/docs/sdks/c-sharp/quickstart), or [TypeScript](/docs/sdks/typescript/quickstart).
|
||||
|
||||
If you are planning to use SpacetimeDB with the Unity game engine, you can skip right to the [Unity Comprehensive Tutorial](/docs/unity/part-1) or check out our example game, [BitcraftMini](/docs/unity/part-3).
|
||||
|
||||
+14
-3
@@ -1,12 +1,23 @@
|
||||
"use strict";
|
||||
var __assign = (this && this.__assign) || function () {
|
||||
__assign = Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign.apply(this, arguments);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
function page(title, slug, path, props) {
|
||||
return { type: 'page', path, slug, title, ...props };
|
||||
return __assign({ type: 'page', path: path, slug: slug, title: title }, props);
|
||||
}
|
||||
function section(title) {
|
||||
return { type: 'section', title };
|
||||
return { type: 'section', title: title };
|
||||
}
|
||||
const nav = {
|
||||
var nav = {
|
||||
items: [
|
||||
section('Intro'),
|
||||
page('Overview', 'index', 'index.md'), // TODO(BREAKING): For consistency & clarity, 'index' slug should be renamed 'intro'?
|
||||
|
||||
+2
-2
@@ -34,7 +34,7 @@ The tag is an index into the [`SumType.variants`](#sumtype) array of the value's
|
||||
|
||||
### `ProductValue`
|
||||
|
||||
An instance of a [`ProductType`](#producttype). `ProductValue`s are encoded as JSON arrays. Each element of the `ProductValue` array is of the type of the corresponding index in the [`ProductType.elements`](#productype) array of the value's [`ProductType`](#producttype).
|
||||
An instance of a [`ProductType`](#producttype). `ProductValue`s are encoded as JSON arrays. Each element of the `ProductValue` array is of the type of the corresponding index in the [`ProductType.elements`](#producttype) array of the value's [`ProductType`](#producttype).
|
||||
|
||||
```json
|
||||
array<AlgebraicValue>
|
||||
@@ -69,7 +69,7 @@ All SATS types are JSON-encoded by converting them to an `AlgebraicValue`, then
|
||||
| --------------------------------------- | ------------------------------------------------------------------------------------ |
|
||||
| [`AlgebraicType`](#algebraictype) | Any SATS type. |
|
||||
| [`SumType`](#sumtype) | Sum types, i.e. tagged unions. |
|
||||
| [`ProductType`](#productype) | Product types, i.e. structures. |
|
||||
| [`ProductType`](#producttype) | Product types, i.e. structures. |
|
||||
| [`BuiltinType`](#builtintype) | Built-in and primitive types, including booleans, numbers, strings, arrays and maps. |
|
||||
| [`AlgebraicTypeRef`](#algebraictyperef) | An indirect reference to a type, used to implement recursive types. |
|
||||
|
||||
|
||||
@@ -16,10 +16,10 @@ The SpacetimeDB client C# for Rust contains all the tools you need to build nati
|
||||
- [Method `SpacetimeDBClient.Connect`](#method-spacetimedbclientconnect)
|
||||
- [Event `SpacetimeDBClient.onIdentityReceived`](#event-spacetimedbclientonidentityreceived)
|
||||
- [Event `SpacetimeDBClient.onConnect`](#event-spacetimedbclientonconnect)
|
||||
- [Query subscriptions & one-time actions](#subscribe-to-queries)
|
||||
- [Subscribe to queries](#subscribe-to-queries)
|
||||
- [Method `SpacetimeDBClient.Subscribe`](#method-spacetimedbclientsubscribe)
|
||||
- [Event `SpacetimeDBClient.onSubscriptionApplied`](#event-spacetimedbclientonsubscriptionapplied)
|
||||
- [Method `SpacetimeDBClient.OneOffQuery`](#method-spacetimedbclientoneoffquery)
|
||||
- [Method \[`SpacetimeDBClient.OneOffQuery`\]](#method-spacetimedbclientoneoffquery)
|
||||
- [View rows of subscribed tables](#view-rows-of-subscribed-tables)
|
||||
- [Class `{TABLE}`](#class-table)
|
||||
- [Static Method `{TABLE}.Iter`](#static-method-tableiter)
|
||||
@@ -45,7 +45,6 @@ The SpacetimeDB client C# for Rust contains all the tools you need to build nati
|
||||
- [Static Property `AuthToken.Token`](#static-property-authtokentoken)
|
||||
- [Static Method `AuthToken.SaveToken`](#static-method-authtokensavetoken)
|
||||
- [Class `Identity`](#class-identity)
|
||||
- [Class `Identity`](#class-identity-1)
|
||||
- [Customizing logging](#customizing-logging)
|
||||
- [Interface `ISpacetimeDBLogger`](#interface-ispacetimedblogger)
|
||||
- [Class `ConsoleLogger`](#class-consolelogger)
|
||||
@@ -104,7 +103,7 @@ The Unity SpacetimeDB SDK relies on there being a `NetworkManager` somewhere in
|
||||
|
||||

|
||||
|
||||
This component will handle updating and closing the [`SpacetimeDBClient.instance`](#property-spacetimedbclientinstance) for you, but will not call [`SpacetimeDBClient.Connect`](#method-spacetimedbclientconnect), you still need to handle that yourself. See the [Unity Quickstart](./UnityQuickStart) and [Unity Tutorial](./UnityTutorialPart1) for more information.
|
||||
This component will handle updating and closing the [`SpacetimeDBClient.instance`](#property-spacetimedbclientinstance) for you, but will not call [`SpacetimeDBClient.Connect`](#method-spacetimedbclientconnect), you still need to handle that yourself. See the [Unity Tutorial](/docs/unity-tutorial) for more information.
|
||||
|
||||
### Method `SpacetimeDBClient.Connect`
|
||||
|
||||
@@ -172,7 +171,7 @@ class SpacetimeDBClient {
|
||||
}
|
||||
```
|
||||
|
||||
Called when we receive an auth token, [`Identity`](#class-identity) and [`Address`](#class-address) from the server. The [`Identity`](#class-identity) serves as a unique public identifier for a user of the database. It can be for several purposes, such as filtering rows in a database for the rows created by a particular user. The auth token is a private access token that allows us to assume an identity. The [`Address`](#class-address) is opaque identifier for a client connection to a database, intended to differentiate between connections from the same [`Identity`](#class-identity).
|
||||
Called when we receive an auth token, [`Identity`](#class-identity) and `Address` from the server. The [`Identity`](#class-identity) serves as a unique public identifier for a user of the database. It can be for several purposes, such as filtering rows in a database for the rows created by a particular user. The auth token is a private access token that allows us to assume an identity. The `Address` is opaque identifier for a client connection to a database, intended to differentiate between connections from the same [`Identity`](#class-identity).
|
||||
|
||||
To store the auth token to the filesystem, use the static method [`AuthToken.SaveToken`](#static-method-authtokensavetoken). You may also want to store the returned [`Identity`](#class-identity) in a local variable.
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@ impl DbConnection {
|
||||
|
||||
`frame_tick` will advance the connection until no work remains, then return rather than blocking or `await`-ing. Games might arrange for this message to be called every frame. `frame_tick` returns `Ok` if the connection remains active afterwards, or `Err` if the connection disconnected before or during the call.
|
||||
|
||||
## Trait `spacetimedb_sdk::DbContext`
|
||||
## Trait `DbContext`
|
||||
|
||||
[`DbConnection`](#type-dbconnection) and [`EventContext`](#type-eventcontext) both implement `DbContext`, which allows
|
||||
|
||||
@@ -185,7 +185,7 @@ impl SubscriptionBuilder {
|
||||
}
|
||||
```
|
||||
|
||||
Register a callback to run when the subscription is applied and the matching rows are inserted into the client cache. The [`EventContext`](#type-module_bindings-eventcontext) passed to the callback will have `Event::SubscribeApplied` as its `event`.
|
||||
Register a callback to run when the subscription is applied and the matching rows are inserted into the client cache. The [`EventContext`](#type-eventcontext) passed to the callback will have `Event::SubscribeApplied` as its `event`.
|
||||
|
||||
#### Method `subscribe`
|
||||
|
||||
|
||||
@@ -471,7 +471,7 @@ Identity.fromString(str: string): Identity
|
||||
|
||||
### Class `Address`
|
||||
|
||||
An opaque identifier for a client connection to a database, intended to differentiate between connections from the same [`Identity`](#type-identity).
|
||||
An opaque identifier for a client connection to a database, intended to differentiate between connections from the same [`Identity`](#class-identity).
|
||||
|
||||
Defined in [spacetimedb-sdk.address](https://github.com/clockworklabs/spacetimedb-typescript-sdk/blob/main/src/address.ts):
|
||||
|
||||
@@ -561,9 +561,8 @@ The generated class has a field for each of the table's columns, whose names are
|
||||
| Properties | Description |
|
||||
| ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [`Table.name`](#table-name) | The name of the class. |
|
||||
| [`Table.tableName`](#table-tableName) | The name of the table in the database. |
|
||||
| [`Table.tableName`](#table-tablename) | The name of the table in the database. |
|
||||
| Methods | |
|
||||
| [`Table.isEqual`](#table-isequal) | Method to compare two identities. |
|
||||
| [`Table.all`](#table-all) | Return all the subscribed rows in the table. |
|
||||
| [`Table.filterBy{COLUMN}`](#table-filterbycolumn) | Autogenerated; return subscribed rows with a given value in a particular column. `{COLUMN}` is a placeholder for a column name. |
|
||||
| [`Table.findBy{COLUMN}`](#table-findbycolumn) | Autogenerated; return a subscribed row with a given value in a particular unique column. `{COLUMN}` is a placeholder for a column name. |
|
||||
@@ -857,7 +856,7 @@ Person.onUpdate((oldPerson, newPerson, reducerEvent) => {
|
||||
|
||||
### {Table} removeOnUpdate
|
||||
|
||||
Unregister a previously-registered [`onUpdate`](#table-onUpdate) callback.
|
||||
Unregister a previously-registered [`onUpdate`](#table-onupdate) callback.
|
||||
|
||||
```ts
|
||||
{Table}.removeOnUpdate(callback: (oldValue: {Table}, newValue: {Table}, reducerEvent: ReducerEvent | undefined) => void): void
|
||||
@@ -912,7 +911,7 @@ Person.onDelete((person, reducerEvent) => {
|
||||
|
||||
### {Table} removeOnDelete
|
||||
|
||||
Unregister a previously-registered [`onDelete`](#table-onDelete) callback.
|
||||
Unregister a previously-registered [`onDelete`](#table-ondelete) callback.
|
||||
|
||||
```ts
|
||||
{Table}.removeOnDelete(callback: (value: {Table}, reducerEvent: ReducerEvent | undefined) => void): void
|
||||
|
||||
@@ -119,5 +119,5 @@ We chose ECS for this example project because it promotes scalability, modularit
|
||||
|
||||
From here, the tutorial continues with your favorite server module language of choice:
|
||||
|
||||
- [Rust](part-2a-rust.md)
|
||||
- [C#](part-2b-csharp.md)
|
||||
- [Rust](part-2a-rust)
|
||||
- [C#](part-2b-c-sharp)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# The SpacetimeDB WebSocket API
|
||||
|
||||
As an extension of the [HTTP API](/doc/http-api-reference), SpacetimeDB offers a WebSocket API. Clients can subscribe to a database via a WebSocket connection to receive streaming updates as the database changes, and send requests to invoke reducers. Messages received from the server over a WebSocket will follow the same total ordering of transactions as are committed to the database.
|
||||
As an extension of the [HTTP API](/docs/http), SpacetimeDB offers a WebSocket API. Clients can subscribe to a database via a WebSocket connection to receive streaming updates as the database changes, and send requests to invoke reducers. Messages received from the server over a WebSocket will follow the same total ordering of transactions as are committed to the database.
|
||||
|
||||
The SpacetimeDB SDKs comminicate with their corresponding database using the WebSocket API.
|
||||
|
||||
|
||||
+4
-1
@@ -5,10 +5,13 @@
|
||||
"main": "index.js",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.10.2",
|
||||
"tsx": "^4.19.2",
|
||||
"typescript": "^5.3.2"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc"
|
||||
"build": "tsc nav.ts --outDir docs",
|
||||
"check-links": "tsx scripts/checkLinks.ts"
|
||||
},
|
||||
"author": "Clockwork Labs",
|
||||
"license": "ISC"
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import nav from '../nav'; // Import the nav object directly
|
||||
|
||||
// Function to map slugs to file paths from nav.ts
|
||||
function extractSlugToPathMap(nav: { items: any[] }): Map<string, string> {
|
||||
const slugToPath = new Map<string, string>();
|
||||
|
||||
function traverseNav(items: any[]): void {
|
||||
items.forEach((item) => {
|
||||
if (item.type === 'page' && item.slug && item.path) {
|
||||
const resolvedPath = path.resolve(__dirname, '../docs', item.path);
|
||||
slugToPath.set(`/docs/${item.slug}`, resolvedPath);
|
||||
} else if (item.type === 'section' && item.items) {
|
||||
traverseNav(item.items); // Recursively traverse sections
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
traverseNav(nav.items);
|
||||
return slugToPath;
|
||||
}
|
||||
|
||||
// Function to assert that all files in slugToPath exist
|
||||
function validatePathsExist(slugToPath: Map<string, string>): void {
|
||||
slugToPath.forEach((filePath, slug) => {
|
||||
if (!fs.existsSync(filePath)) {
|
||||
throw new Error(`File not found: ${filePath} (Referenced by slug: ${slug})`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Function to extract links from markdown files with line numbers
|
||||
function extractLinksFromMarkdown(filePath: string): { link: string; line: number }[] {
|
||||
const fileContent = fs.readFileSync(filePath, 'utf-8');
|
||||
const lines = fileContent.split('\n');
|
||||
const linkRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
|
||||
|
||||
const links: { link: string; line: number }[] = [];
|
||||
lines.forEach((lineContent, index) => {
|
||||
let match: RegExpExecArray | null;
|
||||
while ((match = linkRegex.exec(lineContent)) !== null) {
|
||||
links.push({ link: match[2], line: index + 1 }); // Add 1 to make line numbers 1-based
|
||||
}
|
||||
});
|
||||
|
||||
return links;
|
||||
}
|
||||
|
||||
// Function to resolve relative links using slugs
|
||||
function resolveLink(link: string, currentSlug: string): string {
|
||||
if (link.startsWith('#')) {
|
||||
// If the link is a fragment, resolve it to the current slug
|
||||
return `${currentSlug}${link}`;
|
||||
}
|
||||
|
||||
if (link.startsWith('/')) {
|
||||
// Absolute links are returned as-is
|
||||
return link;
|
||||
}
|
||||
|
||||
// Resolve relative links based on slug
|
||||
const currentSlugDir = path.dirname(currentSlug);
|
||||
const resolvedSlug = path.normalize(path.join(currentSlugDir, link)).replace(/\\/g, '/');
|
||||
return resolvedSlug.startsWith('/docs') ? resolvedSlug : `/docs${resolvedSlug}`;
|
||||
}
|
||||
|
||||
// Function to extract headings from a markdown file
|
||||
function extractHeadingsFromMarkdown(filePath: string): string[] {
|
||||
if (!fs.existsSync(filePath) || !fs.lstatSync(filePath).isFile()) {
|
||||
return []; // Return an empty list if the file does not exist or is not a file
|
||||
}
|
||||
|
||||
const fileContent = fs.readFileSync(filePath, 'utf-8');
|
||||
const headingRegex = /^(#{1,6})\s+(.*)$/gm; // Match markdown headings like # Heading
|
||||
const headings: string[] = [];
|
||||
let match: RegExpExecArray | null;
|
||||
|
||||
while ((match = headingRegex.exec(fileContent)) !== null) {
|
||||
const heading = match[2].trim(); // Extract the heading text
|
||||
const slug = heading
|
||||
.toLowerCase()
|
||||
.replace(/[^\w\- ]+/g, '') // Remove special characters
|
||||
.replace(/\s+/g, '-'); // Replace spaces with hyphens
|
||||
headings.push(slug);
|
||||
}
|
||||
|
||||
return headings;
|
||||
}
|
||||
|
||||
// Function to check if the links in .md files match the slugs in nav.ts and validate fragments
|
||||
function checkLinks(): void {
|
||||
const brokenLinks: { file: string; link: string; line: number }[] = [];
|
||||
let totalFiles = 0;
|
||||
let totalLinks = 0;
|
||||
let validLinks = 0;
|
||||
let invalidLinks = 0;
|
||||
let totalFragments = 0;
|
||||
let validFragments = 0;
|
||||
let invalidFragments = 0;
|
||||
let currentFileFragments = 0;
|
||||
|
||||
// Extract the slug-to-path mapping from nav.ts
|
||||
const slugToPath = extractSlugToPathMap(nav);
|
||||
|
||||
// Validate that all paths in slugToPath exist
|
||||
validatePathsExist(slugToPath);
|
||||
|
||||
console.log(`Validated ${slugToPath.size} paths from nav.ts`);
|
||||
|
||||
// Extract valid slugs
|
||||
const validSlugs = Array.from(slugToPath.keys());
|
||||
|
||||
// Reverse map from file path to slug for current file resolution
|
||||
const pathToSlug = new Map<string, string>();
|
||||
slugToPath.forEach((filePath, slug) => {
|
||||
pathToSlug.set(filePath, slug);
|
||||
});
|
||||
|
||||
// Get all .md files to check
|
||||
const mdFiles = getMarkdownFiles(path.resolve(__dirname, '../docs'));
|
||||
|
||||
totalFiles = mdFiles.length;
|
||||
|
||||
mdFiles.forEach((file) => {
|
||||
const links = extractLinksFromMarkdown(file);
|
||||
totalLinks += links.length;
|
||||
|
||||
const currentSlug = pathToSlug.get(file) || '';
|
||||
|
||||
links.forEach(({ link, line }) => {
|
||||
// Exclude external links (starting with http://, https://, mailto:, etc.)
|
||||
if (/^([a-z][a-z0-9+.-]*):/.test(link)) {
|
||||
return; // Skip external links
|
||||
}
|
||||
|
||||
const siteLinks = ['/install', '/images'];
|
||||
for (const siteLink of siteLinks) {
|
||||
if (link.startsWith(siteLink)) {
|
||||
return; // Skip site links
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Resolve the link
|
||||
const resolvedLink = resolveLink(link, currentSlug);
|
||||
|
||||
// Split the resolved link into base and fragment
|
||||
const [baseLink, fragmentRaw] = resolvedLink.split('#');
|
||||
const fragment: string | null = fragmentRaw || null;
|
||||
|
||||
if (fragment) {
|
||||
totalFragments += 1;
|
||||
}
|
||||
|
||||
// Check if the base link matches a valid slug
|
||||
if (!validSlugs.includes(baseLink)) {
|
||||
brokenLinks.push({ file, link: resolvedLink, line });
|
||||
invalidLinks += 1;
|
||||
return;
|
||||
} else {
|
||||
validLinks += 1;
|
||||
}
|
||||
|
||||
// Validate the fragment, if present
|
||||
if (fragment) {
|
||||
const targetFile = slugToPath.get(baseLink);
|
||||
if (targetFile) {
|
||||
const targetHeadings = extractHeadingsFromMarkdown(targetFile);
|
||||
|
||||
if (!targetHeadings.includes(fragment)) {
|
||||
brokenLinks.push({ file, link: resolvedLink, line });
|
||||
invalidFragments += 1;
|
||||
invalidLinks += 1;
|
||||
} else {
|
||||
validFragments += 1;
|
||||
if (baseLink === currentSlug) {
|
||||
currentFileFragments += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (brokenLinks.length > 0) {
|
||||
console.error(`\nFound ${brokenLinks.length} broken links:`);
|
||||
brokenLinks.forEach(({ file, link, line }) => {
|
||||
console.error(`File: ${file}:${line}, Link: ${link}`);
|
||||
});
|
||||
} else {
|
||||
console.log('All links are valid!');
|
||||
}
|
||||
|
||||
// Print statistics
|
||||
console.log('\n=== Link Validation Statistics ===');
|
||||
console.log(`Total markdown files processed: ${totalFiles}`);
|
||||
console.log(`Total links processed: ${totalLinks}`);
|
||||
console.log(` Valid links: ${validLinks}`);
|
||||
console.log(` Invalid links: ${invalidLinks}`);
|
||||
console.log(`Total links with fragments processed: ${totalFragments}`);
|
||||
console.log(` Valid links with fragments: ${validFragments}`);
|
||||
console.log(` Invalid links with fragments: ${invalidFragments}`);
|
||||
console.log(`Fragments referring to the current file: ${currentFileFragments}`);
|
||||
console.log('=================================');
|
||||
|
||||
if (brokenLinks.length > 0) {
|
||||
process.exit(1); // Exit with an error code if there are broken links
|
||||
}
|
||||
}
|
||||
|
||||
// Function to get all markdown files recursively
|
||||
function getMarkdownFiles(dir: string): string[] {
|
||||
let files: string[] = [];
|
||||
const items = fs.readdirSync(dir);
|
||||
|
||||
items.forEach((item) => {
|
||||
const fullPath = path.join(dir, item);
|
||||
const stat = fs.lstatSync(fullPath);
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
files = files.concat(getMarkdownFiles(fullPath)); // Recurse into directories
|
||||
} else if (fullPath.endsWith('.md')) {
|
||||
files.push(fullPath);
|
||||
}
|
||||
});
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
checkLinks();
|
||||
@@ -3,6 +3,8 @@
|
||||
"target": "ESNext",
|
||||
"module": "commonjs",
|
||||
"outDir": "./docs",
|
||||
"esModuleInterop": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true
|
||||
}
|
||||
}
|
||||
|
||||
+189
@@ -2,7 +2,196 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@esbuild/aix-ppc64@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz#51299374de171dbd80bb7d838e1cfce9af36f353"
|
||||
integrity sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==
|
||||
|
||||
"@esbuild/android-arm64@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz#58565291a1fe548638adb9c584237449e5e14018"
|
||||
integrity sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==
|
||||
|
||||
"@esbuild/android-arm@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.23.1.tgz#5eb8c652d4c82a2421e3395b808e6d9c42c862ee"
|
||||
integrity sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==
|
||||
|
||||
"@esbuild/android-x64@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.23.1.tgz#ae19d665d2f06f0f48a6ac9a224b3f672e65d517"
|
||||
integrity sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==
|
||||
|
||||
"@esbuild/darwin-arm64@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz#05b17f91a87e557b468a9c75e9d85ab10c121b16"
|
||||
integrity sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==
|
||||
|
||||
"@esbuild/darwin-x64@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz#c58353b982f4e04f0d022284b8ba2733f5ff0931"
|
||||
integrity sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==
|
||||
|
||||
"@esbuild/freebsd-arm64@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz#f9220dc65f80f03635e1ef96cfad5da1f446f3bc"
|
||||
integrity sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==
|
||||
|
||||
"@esbuild/freebsd-x64@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz#69bd8511fa013b59f0226d1609ac43f7ce489730"
|
||||
integrity sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==
|
||||
|
||||
"@esbuild/linux-arm64@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz#8050af6d51ddb388c75653ef9871f5ccd8f12383"
|
||||
integrity sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==
|
||||
|
||||
"@esbuild/linux-arm@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz#ecaabd1c23b701070484990db9a82f382f99e771"
|
||||
integrity sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==
|
||||
|
||||
"@esbuild/linux-ia32@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz#3ed2273214178109741c09bd0687098a0243b333"
|
||||
integrity sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==
|
||||
|
||||
"@esbuild/linux-loong64@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz#a0fdf440b5485c81b0fbb316b08933d217f5d3ac"
|
||||
integrity sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==
|
||||
|
||||
"@esbuild/linux-mips64el@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz#e11a2806346db8375b18f5e104c5a9d4e81807f6"
|
||||
integrity sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==
|
||||
|
||||
"@esbuild/linux-ppc64@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz#06a2744c5eaf562b1a90937855b4d6cf7c75ec96"
|
||||
integrity sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==
|
||||
|
||||
"@esbuild/linux-riscv64@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz#65b46a2892fc0d1af4ba342af3fe0fa4a8fe08e7"
|
||||
integrity sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==
|
||||
|
||||
"@esbuild/linux-s390x@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz#e71ea18c70c3f604e241d16e4e5ab193a9785d6f"
|
||||
integrity sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==
|
||||
|
||||
"@esbuild/linux-x64@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz#d47f97391e80690d4dfe811a2e7d6927ad9eed24"
|
||||
integrity sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==
|
||||
|
||||
"@esbuild/netbsd-x64@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz#44e743c9778d57a8ace4b72f3c6b839a3b74a653"
|
||||
integrity sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==
|
||||
|
||||
"@esbuild/openbsd-arm64@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz#05c5a1faf67b9881834758c69f3e51b7dee015d7"
|
||||
integrity sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==
|
||||
|
||||
"@esbuild/openbsd-x64@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz#2e58ae511bacf67d19f9f2dcd9e8c5a93f00c273"
|
||||
integrity sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==
|
||||
|
||||
"@esbuild/sunos-x64@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz#adb022b959d18d3389ac70769cef5a03d3abd403"
|
||||
integrity sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==
|
||||
|
||||
"@esbuild/win32-arm64@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz#84906f50c212b72ec360f48461d43202f4c8b9a2"
|
||||
integrity sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==
|
||||
|
||||
"@esbuild/win32-ia32@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz#5e3eacc515820ff729e90d0cb463183128e82fac"
|
||||
integrity sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==
|
||||
|
||||
"@esbuild/win32-x64@0.23.1":
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz#81fd50d11e2c32b2d6241470e3185b70c7b30699"
|
||||
integrity sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==
|
||||
|
||||
"@types/node@^22.10.2":
|
||||
version "22.10.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.10.2.tgz#a485426e6d1fdafc7b0d4c7b24e2c78182ddabb9"
|
||||
integrity sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==
|
||||
dependencies:
|
||||
undici-types "~6.20.0"
|
||||
|
||||
esbuild@~0.23.0:
|
||||
version "0.23.1"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.23.1.tgz#40fdc3f9265ec0beae6f59824ade1bd3d3d2dab8"
|
||||
integrity sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==
|
||||
optionalDependencies:
|
||||
"@esbuild/aix-ppc64" "0.23.1"
|
||||
"@esbuild/android-arm" "0.23.1"
|
||||
"@esbuild/android-arm64" "0.23.1"
|
||||
"@esbuild/android-x64" "0.23.1"
|
||||
"@esbuild/darwin-arm64" "0.23.1"
|
||||
"@esbuild/darwin-x64" "0.23.1"
|
||||
"@esbuild/freebsd-arm64" "0.23.1"
|
||||
"@esbuild/freebsd-x64" "0.23.1"
|
||||
"@esbuild/linux-arm" "0.23.1"
|
||||
"@esbuild/linux-arm64" "0.23.1"
|
||||
"@esbuild/linux-ia32" "0.23.1"
|
||||
"@esbuild/linux-loong64" "0.23.1"
|
||||
"@esbuild/linux-mips64el" "0.23.1"
|
||||
"@esbuild/linux-ppc64" "0.23.1"
|
||||
"@esbuild/linux-riscv64" "0.23.1"
|
||||
"@esbuild/linux-s390x" "0.23.1"
|
||||
"@esbuild/linux-x64" "0.23.1"
|
||||
"@esbuild/netbsd-x64" "0.23.1"
|
||||
"@esbuild/openbsd-arm64" "0.23.1"
|
||||
"@esbuild/openbsd-x64" "0.23.1"
|
||||
"@esbuild/sunos-x64" "0.23.1"
|
||||
"@esbuild/win32-arm64" "0.23.1"
|
||||
"@esbuild/win32-ia32" "0.23.1"
|
||||
"@esbuild/win32-x64" "0.23.1"
|
||||
|
||||
fsevents@~2.3.3:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
|
||||
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
|
||||
|
||||
get-tsconfig@^4.7.5:
|
||||
version "4.8.1"
|
||||
resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.8.1.tgz#8995eb391ae6e1638d251118c7b56de7eb425471"
|
||||
integrity sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==
|
||||
dependencies:
|
||||
resolve-pkg-maps "^1.0.0"
|
||||
|
||||
resolve-pkg-maps@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f"
|
||||
integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==
|
||||
|
||||
tsx@^4.19.2:
|
||||
version "4.19.2"
|
||||
resolved "https://registry.yarnpkg.com/tsx/-/tsx-4.19.2.tgz#2d7814783440e0ae42354d0417d9c2989a2ae92c"
|
||||
integrity sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==
|
||||
dependencies:
|
||||
esbuild "~0.23.0"
|
||||
get-tsconfig "^4.7.5"
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.3"
|
||||
|
||||
typescript@^5.3.2:
|
||||
version "5.3.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.2.tgz#00d1c7c1c46928c5845c1ee8d0cc2791031d4c43"
|
||||
integrity sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==
|
||||
|
||||
undici-types@~6.20.0:
|
||||
version "6.20.0"
|
||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433"
|
||||
integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==
|
||||
|
||||
Reference in New Issue
Block a user