first impl of $$uid

pull/15185/head
adiguba 2 years ago
parent 7f8acb8a37
commit 657a09aa4c

@ -500,3 +500,5 @@ declare namespace $host {
/** @deprecated */
export const toString: never;
}
declare const $$uid: string;

@ -220,7 +220,7 @@ function get_component_name(filename) {
return name[0].toUpperCase() + name.slice(1);
}
const RESERVED = ['$$props', '$$restProps', '$$slots'];
const RESERVED = ['$$props', '$$restProps', '$$slots', '$$uid'];
/**
* @param {Program} ast

@ -35,6 +35,10 @@ export function Identifier(node, context) {
context.state.analysis.uses_slots = true;
}
if (node.name === '$$uid') {
context.state.analysis.uses_uid = true;
}
if (context.state.analysis.runes) {
if (
is_rune(node.name) &&

@ -565,6 +565,10 @@ export function client_component(analysis, options) {
component_block.body.unshift(b.stmt(b.call('$.check_target', b.id('new.target'))));
}
if (analysis.uses_uid) {
component_block.body.unshift(b.const('$$uid', b.call('$.create_uid')));
}
if (state.events.size > 0) {
body.push(
b.stmt(b.call('$.delegate', b.array(Array.from(state.events).map((name) => b.literal(name)))))

@ -244,6 +244,10 @@ export function server_component(analysis, options) {
.../** @type {Statement[]} */ (template.body)
]);
if (analysis.uses_uid) {
component_block.body.unshift(b.const('$$uid', b.call('$.create_uid', b.id('$$payload'))));
}
let should_inject_context = dev || analysis.needs_context;
if (should_inject_context) {

@ -50,6 +50,8 @@ export interface ComponentAnalysis extends Analysis {
uses_slots: boolean;
uses_component_bindings: boolean;
uses_render_tags: boolean;
/** Whether the component uses `$$uid` */
uses_uid: boolean;
needs_context: boolean;
needs_props: boolean;
/** Set to the first event directive (on:x) found on a DOM element in the code */

@ -249,3 +249,24 @@ export function append(anchor, dom) {
anchor.before(/** @type {Node} */ (dom));
}
let NEXT_UID = 100;
/**
* Create (or hydrate) an unique UID for the component instance.
*/
export function create_uid() {
let uid;
if (
hydrating &&
hydrate_node &&
hydrate_node.nodeType === Node.COMMENT_NODE &&
hydrate_node.textContent?.startsWith('#s')
) {
uid = hydrate_node.textContent.substring(1);
hydrate_next();
} else {
uid = 'c' + NEXT_UID++;
}
return uid;
}

@ -95,7 +95,8 @@ export {
mathml_template,
template,
template_with_script,
text
text,
create_uid
} from './dom/template.js';
export { derived, derived_safe_equal } from './reactivity/deriveds.js';
export {

@ -28,14 +28,15 @@ const INVALID_ATTR_NAME_CHAR_REGEX =
* @param {Payload} to_copy
* @returns {Payload}
*/
export function copy_payload({ out, css, head }) {
export function copy_payload({ out, css, head, uid }) {
return {
out,
css: new Set(css),
head: {
title: head.title,
out: head.out
}
},
uid
};
}
@ -48,6 +49,7 @@ export function copy_payload({ out, css, head }) {
export function assign_payload(p1, p2) {
p1.out = p2.out;
p1.head = p2.head;
p1.uid = p2.uid;
}
/**
@ -83,17 +85,27 @@ export function element(payload, tag, attributes_fn = noop, children_fn = noop)
*/
export let on_destroy = [];
function create_uid_generator() {
let uid = 100;
return () => 's' + uid++;
}
/**
* Only available on the server and when compiling with the `server` option.
* Takes a component and returns an object with `body` and `head` properties on it, which you can use to populate the HTML when server-rendering your app.
* @template {Record<string, any>} Props
* @param {import('svelte').Component<Props> | ComponentType<SvelteComponent<Props>>} component
* @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any> }} [options]
* @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>, uid?: () => string }} [options]
* @returns {RenderOutput}
*/
export function render(component, options = {}) {
/** @type {Payload} */
const payload = { out: '', css: new Set(), head: { title: '', out: '' } };
const payload = {
out: '',
css: new Set(),
head: { title: '', out: '' },
uid: options.uid ?? create_uid_generator()
};
const prev_on_destroy = on_destroy;
on_destroy = [];
@ -526,6 +538,17 @@ export function once(get_value) {
};
}
/**
* Create an unique ID
* @param {Payload} payload
* @returns {string}
*/
export function create_uid(payload) {
const UID = payload.uid();
payload.out += '<!--#' + UID + '-->';
return UID;
}
export { attr, clsx };
export { html } from './blocks/html.js';

@ -18,6 +18,8 @@ export interface Payload {
title: string;
out: string;
};
/** Function that generates a unique ID */
uid: () => string;
}
export interface RenderOutput {

@ -3159,4 +3159,6 @@ declare namespace $host {
export const toString: never;
}
declare const $$uid: string;
//# sourceMappingURL=index.d.ts.map

Loading…
Cancel
Save