Page MenuHomeSealhub

No OneTemporary

diff --git a/src/index.ts b/src/index.ts
index dabad54..11607bb 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,97 +1,98 @@
import { Readable } from "stream";
import pipeInto from "./pipe-into";
import { Slot } from "./slot";
import { Stringifiable, stringify } from "./stringify";
export { Slot } from "./slot";
export type Templatable = Stringifiable | Slot;
async function* templateGen(
strings: TemplateStringsArray,
...params: Templatable[]
) {
for (let string of strings) {
yield string;
const param = params.shift();
yield param;
}
yield null;
}
class TempStream extends Readable {
is_piping_substream = false;
id = Math.random();
constructor(public generator: ReturnType<typeof templateGen>) {
super();
}
_read() {
if (this.is_piping_substream) {
return;
}
const next = this.generator.next();
next.then(async (result) => {
this.handleResult(
result,
(data) => {
this.push(data);
},
() => this.emit("end")
);
}).catch(console.error);
}
async handleSlot(slot: Slot, push: (data: any) => void) {
let suffix = "";
let changed = slot.changed;
let finished = false;
slot.on("change", () => (changed = true));
let new_result;
while (!finished && !changed) {
new_result = await this.generator.next();
await this.handleResult(
new_result,
(data) => {
+ if (data === null) return;
suffix += data;
},
() => (finished = true)
);
}
push(slot.value + suffix);
}
async handleResult(
result: IteratorResult<any>,
push: (data: any) => void,
end: () => void
) {
if (result.done) {
push(null);
end();
}
if (result.value instanceof Readable) {
this.is_piping_substream = true;
await pipeInto(result.value, push).then(() => {
this.is_piping_substream = false;
this._read();
});
} else if (result.value instanceof Slot) {
await this.handleSlot(result.value, push);
} else {
push(await stringify(result.value));
}
}
push(data: unknown): boolean {
super.push(data);
return true;
}
}
export function tempstream(
strings: TemplateStringsArray,
...params: Templatable[]
): Readable {
return new TempStream(templateGen(strings, ...params));
}
diff --git a/src/test.ts b/src/test.ts
index 40c4738..b27c83f 100644
--- a/src/test.ts
+++ b/src/test.ts
@@ -1,71 +1,79 @@
import assert from "assert";
import { Readable } from "stream";
import { promisify } from "util";
import { Templatable, tempstream } from ".";
import { Slot } from "./slot";
import streamToString from "./tostring";
const name = new Slot("noname");
const st = (time: number, cb: () => void) => setTimeout(cb, time);
const sleep = promisify(st);
// a test
function html(
strings: TemplateStringsArray,
...params: Templatable[]
): Readable {
const title = new Slot("Default page title");
setTimeout(() => title.set("Changed page title"), 3000);
console.error(
"try playing around with the above timeout. Weird things happen when you go to e.g. 3000"
);
// process.exit(1);
return tempstream/* HTML */ `<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<title>${title}</title>
</head>
<body>
${tempstream(strings, ...params)}
</body> `;
}
// template`hello ${world}, and ${name}`.pipe(process.stdout);
describe("tempstream", () => {
it("renders properly in the basic case", async () => {
const list_items = Promise.resolve(
["one", "two", "three"].map((e) => `<li>${e}</li>`)
);
const title = new Slot("Default page title");
setTimeout(() => title.set("Changed page title"), 20);
const slept = sleep(100).then(() => "slept");
const result =
await streamToString(tempstream/* HTML */ `<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<title>${title}</title>
</head>
<body>
hello World, I ${slept}.
<ul>
${list_items}
</ul>
</body> `);
assert.strictEqual(
result,
`<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<title>Changed page title</title>
</head>
<body>
hello World, I slept.
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
</body> `
);
});
+
+ it("doesn't add unecessary 'null' when encountering an unresolved slot", async () => {
+ const title = new Slot("unchanged");
+ const result = await streamToString(
+ tempstream`<title>${title}</title>`
+ );
+ assert.strictEqual(result, `<title>unchanged</title>`);
+ });
});

File Metadata

Mime Type
text/x-diff
Expires
Sat, Nov 8, 03:41 (23 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1033983
Default Alt Text
(4 KB)

Event Timeline