diff --git a/astro.config.mjs b/astro.config.mjs index e89a4c3..f4c293f 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,5 +1,6 @@ import { defineConfig } from "astro/config"; import starlight from "@astrojs/starlight"; +import starlightBlog from "starlight-blog"; // https://astro.build/config export default defineConfig({ @@ -12,6 +13,7 @@ export default defineConfig({ replacesTitle: true, }, customCss: ["./src/custom.css"], + plugins: [starlightBlog()], // social: { // github: 'https://github.com/withastro/starlight', // }, diff --git a/package-lock.json b/package-lock.json index 67328f3..437eb3f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,8 @@ "@astrojs/starlight": "^0.25.0", "astro": "^4.10.2", "ses": "^1.5.0", - "sharp": "^0.32.5" + "sharp": "^0.32.5", + "starlight-blog": "^0.12.0" } }, "node_modules/@ampproject/remapping": { @@ -99,6 +100,15 @@ "node": "^18.17.1 || ^20.3.0 || >=21.0.0" } }, + "node_modules/@astrojs/rss": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@astrojs/rss/-/rss-4.0.5.tgz", + "integrity": "sha512-IyJVL6z09AQtxbgLaAwebT3T5YKe4oTHDesqydJv1KLHw+zEzzMCFuuNsEyxjiqu7df9+DDCpDXLj/WRiEUXvw==", + "dependencies": { + "fast-xml-parser": "^4.2.7", + "kleur": "^4.1.5" + } + }, "node_modules/@astrojs/sitemap": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-3.1.6.tgz", @@ -2063,6 +2073,21 @@ "astro": "^4.0.0-beta || ^3.3.0" } }, + "node_modules/astro-remote": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/astro-remote/-/astro-remote-0.3.2.tgz", + "integrity": "sha512-Xwm6Y+ldQEnDB2l1WwVqeUs3QvUX8LtJWnovpXlf8xhpicPu159jXOhDbHZS9wilGO/+/nR67A1qskF8pDvdGQ==", + "dependencies": { + "entities": "^4.5.0", + "marked": "^12.0.0", + "marked-footnote": "^1.2.2", + "marked-smartypants": "^1.1.6", + "ultrahtml": "^1.5.3" + }, + "engines": { + "node": ">=18.14.1" + } + }, "node_modules/astro/node_modules/sharp": { "version": "0.33.4", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.4.tgz", @@ -3040,6 +3065,27 @@ "node": ">=8.6.0" } }, + "node_modules/fast-xml-parser": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", + "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + ], + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -4021,6 +4067,44 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/marked": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-12.0.2.tgz", + "integrity": "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q==", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/marked-footnote": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/marked-footnote/-/marked-footnote-1.2.2.tgz", + "integrity": "sha512-TFBEHwHLSSedub7P6XHHs+dMMOnDeNV5+kFDo4trU//gDd8iM57lg9jr9NGwDifPwLllHwKmFcRNp5uYvO2Fnw==", + "peerDependencies": { + "marked": ">=7.0.0" + } + }, + "node_modules/marked-plaintify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/marked-plaintify/-/marked-plaintify-1.0.1.tgz", + "integrity": "sha512-KQhxtuVWf3Ij3YMiW4ArlgNOVmzOAlP0o/upsu2+h7Q4TCAwG4UvkYTteZF2sDDomXQnNSLmfyAhoR0gx2Orgw==", + "peerDependencies": { + "marked": ">=7.0.0" + } + }, + "node_modules/marked-smartypants": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/marked-smartypants/-/marked-smartypants-1.1.8.tgz", + "integrity": "sha512-2n8oSjL2gSkH6M0dSdRIyLgqqky03iKQkdmoaylmIzwIhYTW204S7ry6zP2iqwSl0zSlJH2xmWgxlZ/4XB1CdQ==", + "dependencies": { + "smartypants": "^0.2.2" + }, + "peerDependencies": { + "marked": ">=4 <15" + } + }, "node_modules/mdast-util-definitions": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz", @@ -6329,6 +6413,15 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" }, + "node_modules/smartypants": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/smartypants/-/smartypants-0.2.2.tgz", + "integrity": "sha512-TzobUYoEft/xBtb2voRPryAUIvYguG0V7Tt3de79I1WfXgCwelqVsGuZSnu3GFGRZhXR90AeEYIM+icuB/S06Q==", + "bin": { + "smartypants": "bin/smartypants.js", + "smartypantsu": "bin/smartypantsu.js" + } + }, "node_modules/source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", @@ -6359,6 +6452,26 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, + "node_modules/starlight-blog": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/starlight-blog/-/starlight-blog-0.12.0.tgz", + "integrity": "sha512-SSNkBQIM6RrumGQQqOv76L5Lcefm6faU2+4armlgQh2zod24aOvuCGUcFi3F//DxOWvIx3WRb7X/VRqs3yNO8A==", + "dependencies": { + "@astrojs/rss": "4.0.5", + "astro-remote": "0.3.2", + "github-slugger": "2.0.0", + "marked": "12.0.2", + "marked-plaintify": "1.0.1", + "ultrahtml": "1.5.3" + }, + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "@astrojs/starlight": ">=0.24.0", + "astro": ">=4.8.6" + } + }, "node_modules/stdin-discarder": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", @@ -6474,6 +6587,11 @@ "node": ">=0.10.0" } }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + }, "node_modules/style-to-object": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", @@ -6608,6 +6726,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ultrahtml": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.5.3.tgz", + "integrity": "sha512-GykOvZwgDWZlTQMtp5jrD4BVL+gNn2NVlVafjcFUJ7taY20tqYdwdoWBFy6GBJsNTZe1GkGPkSl5knQAjtgceg==" + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", diff --git a/package.json b/package.json index 660dd6f..940a64c 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "@astrojs/starlight": "^0.25.0", "astro": "^4.10.2", "ses": "^1.5.0", - "sharp": "^0.32.5" + "sharp": "^0.32.5", + "starlight-blog": "^0.12.0" } } diff --git a/src/content/config.ts b/src/content/config.ts index 45f60b0..78338c7 100644 --- a/src/content/config.ts +++ b/src/content/config.ts @@ -1,6 +1,11 @@ import { defineCollection } from 'astro:content'; import { docsSchema } from '@astrojs/starlight/schema'; +import { blogSchema } from 'starlight-blog/schema' export const collections = { - docs: defineCollection({ schema: docsSchema() }), + docs: defineCollection({ + schema: docsSchema({ + extend: blogSchema, + }), + }), }; diff --git a/src/content/docs/blog/ses-1.6.0.md b/src/content/docs/blog/ses-1.6.0.md new file mode 100644 index 0000000..9d88457 --- /dev/null +++ b/src/content/docs/blog/ses-1.6.0.md @@ -0,0 +1,296 @@ +--- +title: SES 1.6.0 +date: 2024-07-30 +slug: blog/ses-1.6.0 +--- + +[Agoric](https://agoric.com) has released `ses` version +[1.6.0](https://www.npmjs.com/package/ses/v/1.6.0) with changes that +improve compatibility with [Moddable](https://www.moddable.com/)’s XS. +The version maintains backward-compatibility with existing usage and +some usage becomes deprecated, for which support will be removed in a future, +major version. + +### `__options__` + +With this change, the `Compartment` constructor now has a preferred +single-argument form, which will become the only accepted form in a future, +major version. +Until then, `Compartment` accepts both the old and new signatures. + +The deprecated form accepts three optional arguments: + +```js +const compartment = new Compartment(globals, modules, { + name: 'my-compartment', +}); +``` + +The new form accepts a single options bag, and currently requires the +`__options__` option to distinguish the global endowments from an options +object. + +> This is technically a breaking change, but we expect that it is vanishingly +> rare for a compartment to be endowed with an `__options__` global. +> If such code exists, it will need to adopt the new form. + +```js +const compartment = new Compartment({ + __options__: true, + name: 'my-compartment', + globals, + modules, +}); +``` + +In a future, major version, the `__options__` field will become vestigial and the +three-argument form will be an error. + +```js +const compartment = new Compartment({ + name: 'my-compartment', + globals, + modules, +}); +``` + +### `__noNamespaceBox__` + +Likewise, the `import` method of compartments currently returns a promise +for an object with a `namespace` property, which is the namespace. +This differs from XS and the behavior of standard, dynamic `import`. + +```js +const compartment = new Compartment({ + __options__: true, + modules: { + 'my-module-specifier': { + namespace: {default: 42}, + }, + } +}); +// Note the destructuring of namespace: +const { namespace } = await compartment.import('my-module-specifier'); +console.log(namespace.default); // 42 +``` + +The `import` method should simply return a promise for the module namespace +object, just like dynamic `import` and XS. + +Version 1.6.0 introduces a `__noNamespaceBox__` option that makes the eventual +correct behavior available today. + +```js +const compartment = new Compartment({ + __options__: true, + __noNamespaceBox__: true, + modules: { + 'my-module-specifier': { + namespace: {default: 42}, + }, + } +}); +// Note the absence of destructuring { namespace }: +const namespace = await compartment.import('my-module-specifier'); +console.log(namespace.default); // 42 +``` + +This will become the only supported behavior in a future, major version. + +### Module descriptors + +Version 1.6.0 increases module descriptor parity with XS. +[Module descriptors](https://github.com/endojs/endo/blob/master/packages/ses/README.md#module-descriptors) appear in several places in the `Compartment` interface. + +- The `modules` option is an object that maps module specifiers to their + corresponding module descriptor. + These modules are "pre-loaded" at time of construction. +- The `moduleMapHook` is a function that accepts a module specifier and may + return a module descriptor if `import` or `importNow` cannot complete without + it. +- The `importHookNowHook` accepts a module specifier and may return a module + descriptor if `importNow` cannot complete without it. +- The `importHook` accepts a module specifier and may return a module + descriptor or a promise for a module descriptor if `import` cannot complete + without it. + +With version 1.6.0, module descriptors can take most of the forms accepted by XS +and code should begin migrating to prefer those forms. + +- Prior to version 1.6.0, a `StaticModuleRecord`, `ModuleSource`, virtual + static module record, or virtual module source could be used in place of + a module descriptor. + These should now be boxed in a module descriptor with a `source` property. + (Relatedly, we have renamed the `@endo/static-module-record` package to + `@endo/module-source` to better reflect the direction of movement in the + ECMAScript standardization process.) + + ```js + // before: + import { StaticModuleRecord} from '@endo/static-module-record'; + const compartment = new Compartment( + {}, + { + 'my-module-specifier': new StaticModuleRecord(` + export default 42; + `), + }, + ); + console.log(compartment.importNow('my-module-specifier').default); // 42 + ``` + + ```js + // after + import { ModuleSource} from '@endo/module-source'; + const compartment = new Compartment({ + __options__: true, + modules: { + 'my-module-specifier': { + source: new ModuleSource(` + export default 42; + `), + }, + }, + }); + console.log(compartment.importNow('my-module-specifier').default); // 42 + ``` + +- Prior to version 1.6.0, a module namespace object could be used in place + of a module descriptor. + Particularly, the `Compartment` implementation included a `module` method + that could be used to acquire the module namespace object of a module that + has not yet been loaded, such that a module namespace could be used to link + compartments or settle cyclic dependencies. + This practice is deprecated now in favor of using a `namespace` module + descriptor. + + ```js + // before: + const c1 = new Compartment({}, { + 'c1-module-specifier': new StaticModuleRecord(` + export default 42; + `) + }); + const c2 = new Compartment({}, { + 'c2-module-specifier': c1.module('c1-module-specifier'), + }); + ``` + + ```js + // after + const c1 = new Compartment({ + modules: { + 'c1-module-specifier': new ModuleSource(` + export default 42; + `) + }, + }); + const c2 = new Compartment({ + __options__: true, + modules: { + 'c2-module-specifier': { + namespace: 'c1-module-specifier', + compartment: c1, + }, + }, + }); + ``` + + Module descriptors with the `source` key will construct a fresh instance + of the source in this compartment. + Module descriptors with the `namespace` key will link to a module instance in + the designated compartment. + +- Prior to version 1.6.0, a module descriptor with `record` property + could be used to instantiate a module with a different `import.meta.url` than + the associated module specifier. + These descriptors should migrate to `namespace` module descriptors and + must explicitly designate the `compartment` property if they previously + relied on the default `compartment`. + The default compartment for `namespace` and `source` descriptors is the + "parent compartment": the compartment for which `Compartment` is + the initial, intrinsic `compartment.globalThis.Compartment`. + The default compartment for `record` descriptors is child compartment. + + ```js + // before: + const compartment = new Compartment( + {}, + { + 'submodule/dependency': new StaticModuleRecord(` + export default 42; + `), + dependant: { + record: new StaticModuleRecord(` + import meaning from 'dependency'; + export default meaning; + `), + specifier: 'submodule/depenant', + }, + }, + { + resolveHook(importSpecifier, referrerSpecifier) { + const path = referrerSpecifier.split('/'); + path.pop(); + path.push(...importSpecifier.split('/')); + return path.join('/'); + }, + }, + ); + console.log(compartment.importNow('dependant').default); // 42 + ``` + + ```js + // after + const compartment = new Compartment({ + __options__: true, + modules: { + 'submodule/dependency': new ModuleSource(` + export default 42; + `), + dependant: { + record: new ModuleSource(` + import meaning from 'dependency'; + export default meaning; + `), + specifier: 'submodule/depenant', + }, + }, + resolveHook(importSpecifier, referrerSpecifier) { + const path = referrerSpecifier.split('/'); + path.pop(); + path.push(...importSpecifier.split('/')); + return path.join('/'); + }, + }); + console.log(compartment.importNow('dependant').default); // 42 + ``` + +Support for the deprecated forms will be removed in a future, major version. + +### Line numbers + +When running transpiled code on Node, the SES error taming +gives line-numbers into the generated JavaScript, which often don't match the +the original lines. This happens even with the normal development-time +lockdown options setting, + +```js +errorTaming: 'unsafe' +``` + +or setting the environment variable + +```sh +$ export LOCKDOWN_ERROR_TAMING=unsafe +``` + +To get the original line numbers, this release +adds `'unsafe-debug'`. +This `errorTaming: 'unsafe-debug'` setting should be used ***during development +only*** when you can sacrifice more security for a better debugging experience, +as explained at +[`errorTaming` Options](https://github.com/endojs/endo/blob/master/packages/ses/docs/lockdown.md#errortaming-options). +With this setting, when running transpiled code on Node (e.g. tests written in +TypeScript), the stacktrace line-numbers point back into the original source, +as they do on Node without SES.