mpetuska/kmdc

Generate DOM element IDs with lower collision risk

OliverO2 opened this issue · 7 comments

There is code generating DOM element IDs, which looks like this:

  val localId = remember { Random.nextInt(9999) }
  val radioId = remember { "mdc-radio__native-control__$localId" }

The above approach bears some collision risk. This could be avoided and simplified by using a central ID supply function like this:

private val nextDomElementId = 0
fun uniqueDomElementId() = nextDomElementId++

and then use it like this:

  val localId = remember { uniqueDomElementId() }
  val radioId = remember { "mdc-radio__native-control__$localId" }

This would be collision-free almost forever (until an overflow occurs).

Hmm, the problem with this approach is that we'd need to expose ID provider publicly. How about using a timestamp at the time of component initialisation as ID instead?

uniqueDomElementId() could be internal, of course. Seems like even exposing that function would't really hurt in practice. Or am I overlooking something?

We could even change its return value to a properly prefixed string such as "kmdc-{nextDomElementId++}" and use it directly, as a component-specific prefix is not required.

Ah I see, due to the module separation internal is not an option. Still low potential for any kind of abuse even if public, it seems. Timestamps might also work, but I'd favor not having to think about sufficient resolution on fast machines, if possible.

I've recently introduced @MDCInternalDsl annotation that requires opt-in or throws an error when annotated public entities are used outside kmdc repo. It might be enough to have public id factory with this annotation to make it safe-enough for abuse.

Sounds good. Don't copy that shitty code from above. ;-) I forgot a dollar sign, it seems. Maybe this could work "kmdc-${nextDomElementId++}". :-)

The above would work assuming that you initialise the factory with 0 value -> returning 0 on first call and incrementing it to 1...

Yeah, the 0 doesn't matter. But I got that #65 (comment) string template wrong:

We could even change its return value to a properly prefixed string such as "kmdc-{nextDomElementId++}" and use it directly, as a component-specific prefix is not required.