[ci] format
This commit is contained in:
parent
5e46be5468
commit
e3c78c5b16
9 changed files with 56 additions and 44 deletions
|
@ -2,7 +2,7 @@ import { h, Fragment } from 'preact';
|
||||||
import './Counter.css';
|
import './Counter.css';
|
||||||
|
|
||||||
export default function Counter({ children, count }) {
|
export default function Counter({ children, count }) {
|
||||||
const add = () => count.value++
|
const add = () => count.value++;
|
||||||
const subtract = () => count.value--;
|
const subtract = () => count.value--;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -93,7 +93,6 @@ describe('Preact component', () => {
|
||||||
expect(sigs1Raw).to.not.be.undefined;
|
expect(sigs1Raw).to.not.be.undefined;
|
||||||
expect(sigs2Raw).to.not.be.undefined;
|
expect(sigs2Raw).to.not.be.undefined;
|
||||||
|
|
||||||
|
|
||||||
const sigs1 = JSON.parse(sigs1Raw);
|
const sigs1 = JSON.parse(sigs1Raw);
|
||||||
const sigs2 = JSON.parse(sigs2Raw);
|
const sigs2 = JSON.parse(sigs2Raw);
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,6 @@ describe('Using Astro.response in SSR', () => {
|
||||||
const headers = response.headers;
|
const headers = response.headers;
|
||||||
expect(headers.get('one-two')).to.equal('three');
|
expect(headers.get('one-two')).to.equal('three');
|
||||||
expect(headers.get('four-five')).to.equal('six');
|
expect(headers.get('four-five')).to.equal('six');
|
||||||
expect(headers.get('Cache-Control')).to.equal(`max-age=0, s-maxage=86400`)
|
expect(headers.get('Cache-Control')).to.equal(`max-age=0, s-maxage=86400`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,21 +1,25 @@
|
||||||
import type { SignalLike } from './types';
|
|
||||||
import { h, render } from 'preact';
|
import { h, render } from 'preact';
|
||||||
import StaticHtml from './static-html.js';
|
import StaticHtml from './static-html.js';
|
||||||
|
import type { SignalLike } from './types';
|
||||||
|
|
||||||
const sharedSignalMap: Map<string, SignalLike> = new Map();
|
const sharedSignalMap: Map<string, SignalLike> = new Map();
|
||||||
|
|
||||||
export default (element: HTMLElement) =>
|
export default (element: HTMLElement) =>
|
||||||
async (Component: any, props: Record<string, any>, { default: children, ...slotted }: Record<string, any>) => {
|
async (
|
||||||
|
Component: any,
|
||||||
|
props: Record<string, any>,
|
||||||
|
{ default: children, ...slotted }: Record<string, any>
|
||||||
|
) => {
|
||||||
if (!element.hasAttribute('ssr')) return;
|
if (!element.hasAttribute('ssr')) return;
|
||||||
for (const [key, value] of Object.entries(slotted)) {
|
for (const [key, value] of Object.entries(slotted)) {
|
||||||
props[key] = h(StaticHtml, { value, name: key });
|
props[key] = h(StaticHtml, { value, name: key });
|
||||||
}
|
}
|
||||||
let signalsRaw = element.dataset.preactSignals;
|
let signalsRaw = element.dataset.preactSignals;
|
||||||
if(signalsRaw) {
|
if (signalsRaw) {
|
||||||
const { signal } = await import('@preact/signals');
|
const { signal } = await import('@preact/signals');
|
||||||
let signals: Record<string, string> = JSON.parse(element.dataset.preactSignals as string);
|
let signals: Record<string, string> = JSON.parse(element.dataset.preactSignals as string);
|
||||||
for(const [propName, signalId] of Object.entries(signals)) {
|
for (const [propName, signalId] of Object.entries(signals)) {
|
||||||
if(!sharedSignalMap.has(signalId)) {
|
if (!sharedSignalMap.has(signalId)) {
|
||||||
const signalValue = signal(props[propName]);
|
const signalValue = signal(props[propName]);
|
||||||
sharedSignalMap.set(signalId, signalValue);
|
sharedSignalMap.set(signalId, signalValue);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import type { RendererContext, SignalLike, PropNameToSignalMap } from './types';
|
import type { PropNameToSignalMap, RendererContext, SignalLike } from './types';
|
||||||
|
|
||||||
export type Context = {
|
export type Context = {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -19,7 +19,7 @@ export function getContext(result: RendererContext['result']): Context {
|
||||||
return 'p' + this.c.toString();
|
return 'p' + this.c.toString();
|
||||||
},
|
},
|
||||||
signals: new Map(),
|
signals: new Map(),
|
||||||
propsToSignals: new Map()
|
propsToSignals: new Map(),
|
||||||
};
|
};
|
||||||
contexts.set(result, ctx);
|
contexts.set(result, ctx);
|
||||||
return ctx;
|
return ctx;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import type { AstroPreactAttrs, RendererContext } from './types';
|
import { Component as BaseComponent, h } from 'preact';
|
||||||
import { h, Component as BaseComponent } from 'preact';
|
|
||||||
import render from 'preact-render-to-string';
|
import render from 'preact-render-to-string';
|
||||||
import StaticHtml from './static-html.js';
|
|
||||||
import { getContext } from './context.js';
|
import { getContext } from './context.js';
|
||||||
import { restoreSignalsOnProps, serializeSignals } from './signals.js';
|
import { restoreSignalsOnProps, serializeSignals } from './signals.js';
|
||||||
|
import StaticHtml from './static-html.js';
|
||||||
|
import type { AstroPreactAttrs, RendererContext } from './types';
|
||||||
|
|
||||||
const slotName = (str: string) => str.trim().replace(/[-_]([a-z])/g, (_, w) => w.toUpperCase());
|
const slotName = (str: string) => str.trim().replace(/[-_]([a-z])/g, (_, w) => w.toUpperCase());
|
||||||
|
|
||||||
|
@ -38,7 +38,12 @@ function check(this: RendererContext, Component: any, props: Record<string, any>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderToStaticMarkup(this: RendererContext, Component: any, props: Record<string, any>, { default: children, ...slotted }: Record<string, any>) {
|
function renderToStaticMarkup(
|
||||||
|
this: RendererContext,
|
||||||
|
Component: any,
|
||||||
|
props: Record<string, any>,
|
||||||
|
{ default: children, ...slotted }: Record<string, any>
|
||||||
|
) {
|
||||||
const ctx = getContext(this.result);
|
const ctx = getContext(this.result);
|
||||||
|
|
||||||
const slots: Record<string, ReturnType<typeof h>> = {};
|
const slots: Record<string, ReturnType<typeof h>> = {};
|
||||||
|
@ -60,11 +65,10 @@ function renderToStaticMarkup(this: RendererContext, Component: any, props: Reco
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
attrs,
|
attrs,
|
||||||
html
|
html,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reduces console noise by filtering known non-problematic errors.
|
* Reduces console noise by filtering known non-problematic errors.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import type { AstroPreactAttrs, PropNameToSignalMap, SignalLike } from './types';
|
|
||||||
import type { Context } from './context';
|
import type { Context } from './context';
|
||||||
import { incrementId } from './context.js';
|
import { incrementId } from './context.js';
|
||||||
|
import type { AstroPreactAttrs, PropNameToSignalMap, SignalLike } from './types';
|
||||||
|
|
||||||
function isSignal(x: any): x is SignalLike {
|
function isSignal(x: any): x is SignalLike {
|
||||||
return x != null && typeof x === 'object' && typeof x.peek === 'function' && 'value' in x;
|
return x != null && typeof x === 'object' && typeof x.peek === 'function' && 'value' in x;
|
||||||
|
@ -9,40 +9,45 @@ function isSignal(x: any): x is SignalLike {
|
||||||
export function restoreSignalsOnProps(ctx: Context, props: Record<string, any>) {
|
export function restoreSignalsOnProps(ctx: Context, props: Record<string, any>) {
|
||||||
// Restore signal props that were mutated for serialization
|
// Restore signal props that were mutated for serialization
|
||||||
let propMap: PropNameToSignalMap;
|
let propMap: PropNameToSignalMap;
|
||||||
if(ctx.propsToSignals.has(props)) {
|
if (ctx.propsToSignals.has(props)) {
|
||||||
propMap = ctx.propsToSignals.get(props)!
|
propMap = ctx.propsToSignals.get(props)!;
|
||||||
} else {
|
} else {
|
||||||
propMap = new Map();
|
propMap = new Map();
|
||||||
ctx.propsToSignals.set(props, propMap);
|
ctx.propsToSignals.set(props, propMap);
|
||||||
}
|
}
|
||||||
for(const [key, signal] of propMap) {
|
for (const [key, signal] of propMap) {
|
||||||
props[key] = signal;
|
props[key] = signal;
|
||||||
}
|
}
|
||||||
return propMap;
|
return propMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function serializeSignals(ctx: Context, props: Record<string, any>, attrs: AstroPreactAttrs, map: PropNameToSignalMap){
|
export function serializeSignals(
|
||||||
// Check for signals
|
ctx: Context,
|
||||||
const signals: Record<string, string> = {};
|
props: Record<string, any>,
|
||||||
for(const [key, value] of Object.entries(props)) {
|
attrs: AstroPreactAttrs,
|
||||||
if(isSignal(value)) {
|
map: PropNameToSignalMap
|
||||||
// Set the value to the current signal value
|
) {
|
||||||
// This mutates the props on purpose, so that it will be serialized correct.
|
// Check for signals
|
||||||
props[key] = value.peek();
|
const signals: Record<string, string> = {};
|
||||||
map.set(key, value);
|
for (const [key, value] of Object.entries(props)) {
|
||||||
|
if (isSignal(value)) {
|
||||||
let id: string;
|
// Set the value to the current signal value
|
||||||
if(ctx.signals.has(value)) {
|
// This mutates the props on purpose, so that it will be serialized correct.
|
||||||
id = ctx.signals.get(value)!;
|
props[key] = value.peek();
|
||||||
} else {
|
map.set(key, value);
|
||||||
id = incrementId(ctx);
|
|
||||||
ctx.signals.set(value, id);
|
|
||||||
}
|
|
||||||
signals[key] = id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Object.keys(signals).length) {
|
let id: string;
|
||||||
attrs['data-preact-signals'] = JSON.stringify(signals);
|
if (ctx.signals.has(value)) {
|
||||||
|
id = ctx.signals.get(value)!;
|
||||||
|
} else {
|
||||||
|
id = incrementId(ctx);
|
||||||
|
ctx.signals.set(value, id);
|
||||||
|
}
|
||||||
|
signals[key] = id;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.keys(signals).length) {
|
||||||
|
attrs['data-preact-signals'] = JSON.stringify(signals);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { h } from 'preact';
|
||||||
* As a bonus, we can signal to Preact that this subtree is
|
* As a bonus, we can signal to Preact that this subtree is
|
||||||
* entirely static and will never change via `shouldComponentUpdate`.
|
* entirely static and will never change via `shouldComponentUpdate`.
|
||||||
*/
|
*/
|
||||||
const StaticHtml = ({ value, name }: { value: string; name?: string; }) => {
|
const StaticHtml = ({ value, name }: { value: string; name?: string }) => {
|
||||||
if (!value) return null;
|
if (!value) return null;
|
||||||
return h('astro-slot', { name, dangerouslySetInnerHTML: { __html: value } });
|
return h('astro-slot', { name, dangerouslySetInnerHTML: { __html: value } });
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,5 +10,5 @@ export type SignalLike = {
|
||||||
export type PropNameToSignalMap = Map<string, SignalLike>;
|
export type PropNameToSignalMap = Map<string, SignalLike>;
|
||||||
|
|
||||||
export type AstroPreactAttrs = {
|
export type AstroPreactAttrs = {
|
||||||
['data-preact-signals']?: string
|
['data-preact-signals']?: string;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue