Misc Playground/Docs fixes

This commit is contained in:
Jim Hamill
2025-07-15 04:07:59 +00:00
parent 39e2d4b991
commit f71100b28c
13 changed files with 87 additions and 83 deletions
+13 -2
View File
@@ -77,7 +77,7 @@ These guidelines represent best practices. While exceptions may occasionally be
- Often mask underlying issues that should be properly resolved
- Can lead to unintended side-effects throughout the codebase
4. Avoid additional dependencies.
5. Avoid additional dependencies.
Try to avoid pulling in additional packages. Not only can this bloat the project, but can also cause compatibility issues between environments (Web, Node, ESM, etc). We want `@xocash/stack` to "just work" without devs having to tailor build configurations.
@@ -87,7 +87,18 @@ These guidelines represent best practices. While exceptions may occasionally be
- Does not drag in additional dependencies itself (note that `devDependencies` are fine. These will not be installed when leveraged from our packages).
- If the package being used **is heavy** and we have no other choice but to use it, consider whether we should package it separately to avoid problems. For example, if we build a `BlockchainBCHN` adapter, we will likely want to package this on its own under `@xocash/blockchain-bchn` as it only works in NodeJS environments.
5. "When in Rome..."
6. DO NOT use Typescript "enums".
TypeScript enums have several issues that make them problematic:
- They generate unnecessary runtime code and don't tree-shake well, increasing bundle size
- Numeric enums allow unsafe reverse lookups and can be assigned any number value
- They don't work well with module augmentation and can cause circular dependency issues
- They're not compatible with Node.js's --experimental-strip-types feature, which only removes type annotations and doesn't transform enum syntax
Recommended alternatives: Use const objects with `as const` assertions or string literal union types instead, which work seamlessly with Node's type stripping.
7. "When in Rome..."
For conventions not explicitly mentioned, follow the "when in Rome" principle. Try to identify and use the patterns and conventions that are already established elsewhere in the codebase.
+1 -18
View File
@@ -6649,23 +6649,6 @@
"url": "https://dotenvx.com"
}
},
"node_modules/dts-bundle-generator": {
"version": "9.5.1",
"resolved": "https://registry.npmjs.org/dts-bundle-generator/-/dts-bundle-generator-9.5.1.tgz",
"integrity": "sha512-DxpJOb2FNnEyOzMkG11sxO2dmxPjthoVWxfKqWYJ/bI/rT1rvTMktF5EKjAYrRZu6Z6t3NhOUZ0sZ5ZXevOfbA==",
"dev": true,
"license": "MIT",
"dependencies": {
"typescript": ">=5.0.2",
"yargs": "^17.6.0"
},
"bin": {
"dts-bundle-generator": "dist/bin/dts-bundle-generator.js"
},
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/duplexer": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
@@ -14834,6 +14817,7 @@
"version": "0.0.1",
"license": "ISC",
"dependencies": {
"@bitauth/libauth": "^3.0.0",
"@electrum-cash/network": "^4.1.1",
"@electrum-cash/protocol": "2.1.0-development.8075178089",
"@generalprotocols/oracle-client": "^0.0.1",
@@ -14845,7 +14829,6 @@
},
"devDependencies": {
"@types/better-sqlite3": "^7.6.12",
"dts-bundle-generator": "^9.5.1",
"rollup": "^4.45.0",
"rollup-plugin-dts": "^6.2.1"
}
+2
View File
@@ -123,6 +123,7 @@ export default withMermaid({
// TODO: Re-enable once we release documentation
// { text: 'Documentation', link: '/quick-start' },
{ text: 'Tools', link: '/tools/primitives' },
{ text: 'Playground', link: '/playground' },
],
sidebar: {
@@ -134,6 +135,7 @@ export default withMermaid({
{ text: 'Quick Start', link: '/quick-start' },
{ text: 'Architecture', link: '/architecture' },
{ text: 'Best Practices', link: '/api-examples' },
{ text: 'Contributing', link: '/contributing' },
],
},
{
@@ -373,7 +373,7 @@ defineExpose({
display: flex;
flex-direction: column;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
margin-bottom: 1em;
overflow-y: hidden;
}
.editor-container {
@@ -385,20 +385,6 @@ defineExpose({
overflow: hidden; /* Contain overflow */
}
.editor-container .ace_editor {
background: transparent !important;
font-family: var(--vp-font-family-mono);
line-height: var(--vp-code-line-height);
font-size: var(--vp-code-font-size);
flex: 1 1 auto; /* Allow editor to grow */
overflow: auto; /* Enable scrolling */
min-height: 3em;
}
.editor-container .ace_editor .ace_gutter {
background: transparent !important;
}
.editor-buttons {
position: absolute;
padding:10px;
@@ -3,7 +3,13 @@
<head>
<meta charset="utf-8" />
<title>Code Sandbox</title>
<script>
<script type="module">
// NOTE: We want to be able to console.log, etc, structures that contain bigint and also Uint8Array.
// Thus, JSON.stringify isn't sufficient (it cannot do bigint and Uint8Array output is cumbersome).
// So we import our encodeExtendedJson function and use that in place of JSON.stringify.
// TODO: We want to find a nicer way to include the latest version.
import { encodeExtendedJson } from 'https://cdn.jsdelivr.net/npm/@xocash/primitives@0.0.2-development.210/+esm';
// Override console methods to capture and post messages to parent
const originalConsole = window.console;
@@ -17,7 +23,9 @@
type: 'log',
content: args
.map((arg) =>
typeof arg === 'object' ? JSON.stringify(arg) : String(arg),
typeof arg === 'object'
? encodeExtendedJson(arg, 2)
: String(arg),
)
.join(' '),
},
@@ -33,7 +41,9 @@
type: 'info',
content: args
.map((arg) =>
typeof arg === 'object' ? JSON.stringify(arg) : String(arg),
typeof arg === 'object'
? encodeExtendedJson(arg, 2)
: String(arg),
)
.join(' '),
},
@@ -49,7 +59,9 @@
type: 'warn',
content: args
.map((arg) =>
typeof arg === 'object' ? JSON.stringify(arg) : String(arg),
typeof arg === 'object'
? encodeExtendedJson(arg, 2)
: String(arg),
)
.join(' '),
},
@@ -65,7 +77,9 @@
type: 'error',
content: args
.map((arg) =>
typeof arg === 'object' ? JSON.stringify(arg) : String(arg),
typeof arg === 'object'
? encodeExtendedJson(arg, 2)
: String(arg),
)
.join(' '),
},
+2
View File
@@ -0,0 +1,2 @@
<!-- packages/docs/contributing.md -->
<!--@include: ../../../CONTRIBUTING.md-->
+3
View File
@@ -10,6 +10,9 @@ hero:
- theme: brand
text: Tools
link: /tools/primitives
- theme: brand
text: Playground
link: /playground
---
<!--
+2 -3
View File
@@ -17,14 +17,13 @@ import Playground from '@theme/components/Playground.vue'
import { BlockchainElectrum } from '@xocash/stack';
// Instantiate and start the Electrum Blockchain Adapter.
const blockchain = new BlockchainElectrum();
await blockchain.start();
const blockchain = await BlockchainElectrum.from();
// Fetch a transaction.
const tx = await blockchain.fetchTransaction('a23bbd321067fd039da53f007b26f62591e58e6554b0488d83534c032dbca38b');
// Log it to the console.
console.log('Transaction Hex', tx.toHex());
console.log('Transaction:', tx);
```
</Playground>
+13
View File
@@ -1,5 +1,10 @@
// NOTE: This file is used to build type bundles for use with the XO Stack playground.
// The XO Stack Playground uses Monaco Editor - which requires that types are all bundled in a single file.
// (Technically, we can load many individual files, but resolution is incredibly slow and complex)
import dts from 'rollup-plugin-dts';
import { defineConfig } from 'rollup';
import pkg from './package.json' with { type: 'json' };
export default defineConfig({
input: 'dist/index.d.ts',
@@ -7,5 +12,13 @@ export default defineConfig({
file: 'dist/types-bundled.d.ts',
format: 'es',
},
// Omit all dependencies and peer dependencies from the final type bundle.
// TODO: We may actually want to include these, but are unable to get it to work currently.
// The advantage would be that we can produce bundles that also contain dependent types.
// For example: LibAuth.
external: [
...Object.keys(pkg.dependencies || {}),
...Object.keys(pkg.peerDependencies || {}),
],
plugins: [dts()],
});
-14
View File
@@ -1,14 +0,0 @@
{
"compilationOptions": {
"followSymlinks": true
},
"entries": [
{
"filePath": "./src/index.ts",
"outFile": "./dist/types-bundled.d.ts",
"libraries": {
"inlinedLibraries": ["@xocash/primitives"]
}
}
]
}
+1 -1
View File
@@ -34,6 +34,7 @@
"author": "",
"license": "ISC",
"dependencies": {
"@bitauth/libauth": "^3.0.0",
"@electrum-cash/network": "^4.1.1",
"@electrum-cash/protocol": "2.1.0-development.8075178089",
"@generalprotocols/oracle-client": "^0.0.1",
@@ -45,7 +46,6 @@
},
"devDependencies": {
"@types/better-sqlite3": "^7.6.12",
"dts-bundle-generator": "^9.5.1",
"rollup": "^4.45.0",
"rollup-plugin-dts": "^6.2.1"
}
+13
View File
@@ -1,5 +1,10 @@
// NOTE: This file is used to build type bundles for use with the XO Stack playground.
// The XO Stack Playground uses Monaco Editor - which requires that types are all bundled in a single file.
// (Technically, we can load many individual files, but resolution is incredibly slow and complex)
import dts from 'rollup-plugin-dts';
import { defineConfig } from 'rollup';
import pkg from './package.json' with { type: 'json' };
export default defineConfig({
input: 'dist/index.d.ts',
@@ -7,5 +12,13 @@ export default defineConfig({
file: 'dist/types-bundled.d.ts',
format: 'es',
},
// Omit all dependencies and peer dependencies from the final type bundle.
// TODO: We may actually want to include these, but are unable to get it to work currently.
// The advantage would be that we can produce bundles that also contain dependent types.
// For example: LibAuth, Electrum-Network, etc.
external: [
...Object.keys(pkg.dependencies || {}),
...Object.keys(pkg.peerDependencies || {}),
],
plugins: [dts()],
});
@@ -48,13 +48,9 @@ export type BlockchainElectrumEvents = {
};
export type BlockchainElectrumOpts = {
servers: Array<string>;
application: string;
};
export type BlockchainElectrumParams = {
store?: BaseStore;
opts?: Partial<BlockchainElectrumOpts>;
servers?: Array<string>;
application?: string;
};
export class BlockchainElectrum extends BaseBlockchain<
@@ -82,24 +78,20 @@ export class BlockchainElectrum extends BaseBlockchain<
// Options
store: BaseStore;
opts: BlockchainElectrumOpts;
servers: Array<string>;
application: string;
constructor(public readonly params: BlockchainElectrumParams = {}) {
constructor(public readonly opts: BlockchainElectrumOpts = {}) {
super();
// Set the store, or use the memory store by default.
this.store = params.store ?? new StoreInMemory();
// Combine provided options with default options.
this.opts = {
servers: [
this.store = opts.store ?? new StoreInMemory();
this.servers = opts.servers ?? [
'bch.imaginary.cash',
'cashnode.bch.ninja',
'electrum.imaginary.cash',
],
application: 'XOApp',
...params.opts,
};
];
this.application = opts.application ?? 'XOApp';
}
/**
@@ -109,9 +101,9 @@ export class BlockchainElectrum extends BaseBlockchain<
*/
static async from<T extends typeof BlockchainElectrum>(
this: T,
params: BlockchainElectrumParams = {},
opts: BlockchainElectrumOpts = {},
) {
const blockchain = new this(params);
const blockchain = new this(opts);
await blockchain.start();
@@ -125,10 +117,10 @@ export class BlockchainElectrum extends BaseBlockchain<
// Iterate over each server in our list of servers.
// NOTE: We are still using an Electrum Client due to the above bug.
// But, if we cannot connect to the first server, we will try the second (and third if given, etc) as a fallback.
for (const electrumServer of this.opts.servers) {
for (const electrumServer of this.servers) {
// Initialize an Electrum client using the given server.
const electrum = await initializeElectrumClient(
this.opts.application,
this.application,
electrumServer,
);