<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: KID-joker</title>
    <description>The latest articles on DEV Community by KID-joker (@kidjoker).</description>
    <link>https://dev.to/kidjoker</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F958736%2F0f423951-8dc3-4c45-8b99-aa63c9ad276d.jpeg</url>
      <title>DEV Community: KID-joker</title>
      <link>https://dev.to/kidjoker</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kidjoker"/>
    <language>en</language>
    <item>
      <title>I finally shipped the plugin I'd been putting off for years. Then I started questioning why I built it.</title>
      <dc:creator>KID-joker</dc:creator>
      <pubDate>Thu, 21 May 2026 14:13:05 +0000</pubDate>
      <link>https://dev.to/kidjoker/i-finally-shipped-the-plugin-id-been-putting-off-for-years-then-i-started-questioning-why-i-built-1hpf</link>
      <guid>https://dev.to/kidjoker/i-finally-shipped-the-plugin-id-been-putting-off-for-years-then-i-started-questioning-why-i-built-1hpf</guid>
      <description>&lt;p&gt;A few days ago I checked off something that had been sitting in my todo list for a long time.&lt;/p&gt;

&lt;p&gt;It's a small develop plugin called &lt;a href="https://github.com/KID-joker/unplugin-drop-committed" rel="noopener noreferrer"&gt;unplugin-drop-committed&lt;/a&gt;. It removes method calls like &lt;code&gt;console.log&lt;/code&gt; from your code during development — but only the ones that have been committed to Git. Your uncommitted lines are safe. &lt;/p&gt;

&lt;p&gt;The idea came from a real frustration: a colleague had left &lt;code&gt;console.log&lt;/code&gt; calls inside polling loops. The browser console was unusable. I didn't want to ban &lt;code&gt;console.log&lt;/code&gt; globally — I just wanted the committed noise gone.&lt;/p&gt;

&lt;p&gt;Simple enough concept. I had the idea. I never built it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why it sat there so long
&lt;/h2&gt;

&lt;p&gt;I care deeply about DX tooling. Probably more than is professionally sensible. I've filtered job opportunities based on whether I'd be working on developer experience. I think it's underrated craft — the invisible layer that makes other developers' days slightly less painful.&lt;/p&gt;

&lt;p&gt;But DX is almost always low priority at work. There's always a feature to ship, a bug to fix, a deadline to hit. The DX improvements I want to make get pushed to "later". Later becomes the weekend. The weekend fills up. The todo list grows.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/KID-joker/unplugin-drop-committed" rel="noopener noreferrer"&gt;unplugin-drop-committed&lt;/a&gt; sat there for a long time. Not because it was hard. Because I never had the uninterrupted time to start.&lt;/p&gt;




&lt;h2&gt;
  
  
  How AI changed that
&lt;/h2&gt;

&lt;p&gt;I used Claude to help me build it. I want to be clear about what that means: the ideas, the design, the four removal modes — those were mine. What AI gave me was momentum. It handled the boilerplate, suggested approaches I hadn't considered, and kept me from getting stuck on implementation details that would have cost me a whole evening.&lt;/p&gt;

&lt;p&gt;It took a fraction of the time I expected. I finally crossed something off the list.&lt;/p&gt;

&lt;p&gt;For someone like me — someone with a backlog of DX ideas and a shortage of free hours — AI is genuinely liberating. It's not replacing my thinking. It's removing the friction that was keeping my thinking from becoming real things.&lt;/p&gt;




&lt;h2&gt;
  
  
  The question that followed
&lt;/h2&gt;

&lt;p&gt;The satisfaction lasted maybe ten minutes.&lt;/p&gt;

&lt;p&gt;Then I started thinking about who would actually use this.&lt;/p&gt;

&lt;p&gt;AI-assisted development is changing how code gets written. AI agents don't forget to delete their &lt;code&gt;console.log&lt;/code&gt; calls the way humans do — or if they produce noise, it's a different kind. The problem this plugin solves is a human problem, shaped by human habits.&lt;/p&gt;

&lt;p&gt;I asked Claude how I should position the plugin. It suggested: "unplugin-drop-committed helps AI coding agents stay focused — keeping debug output isolated to the module being worked on."&lt;/p&gt;

&lt;p&gt;That's… not wrong. It's actually an interesting reframe. But it also felt like I was watching my motivation quietly shift from "making developers' lives better" to "making AI agents' workflows cleaner."&lt;/p&gt;

&lt;p&gt;DX. AX. Developer Experience. Agent Experience.&lt;/p&gt;

&lt;p&gt;I'm not sure when the transition happened, or if it already has.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I actually believe
&lt;/h2&gt;

&lt;p&gt;I don't think DX is dead. I think the audience is changing, and the best DX tools will be the ones that serve both humans and the agents working alongside them.&lt;/p&gt;

&lt;p&gt;I also think there's something worth preserving about caring whether the developer console is readable. Whether the hot reload feels instant. Whether configuration is intuitive. These things still matter, even if fewer people are writing the code by hand.&lt;/p&gt;

&lt;p&gt;And I'm going to keep building these tools. AI gave me back the time to do it. I'd rather use that time on the things I actually care about than spend it wondering whether caring still counts.&lt;/p&gt;




&lt;p&gt;If you want to try it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/KID-joker/unplugin-drop-committed" rel="noopener noreferrer"&gt;https://github.com/KID-joker/unplugin-drop-committed&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Four modes: strict (committed lines), file (committed files), user (other authors), time (older than N days/months). Vite, Webpack, Rollup, Rspack. Vue and Svelte script blocks included.&lt;/p&gt;

&lt;p&gt;I'd genuinely like to know: do you think DX tooling still matters the same way it did two years ago?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How to keep the type of storage value unchanged?</title>
      <dc:creator>KID-joker</dc:creator>
      <pubDate>Sun, 15 Jan 2023 13:24:03 +0000</pubDate>
      <link>https://dev.to/kidjoker/how-to-keep-the-type-of-storage-value-unchanged-3b3h</link>
      <guid>https://dev.to/kidjoker/how-to-keep-the-type-of-storage-value-unchanged-3b3h</guid>
      <description>&lt;p&gt;Hello, everyone! In September last year, I created a new repository called &lt;a href="https://github.com/KID-joker/proxy-web-storage" rel="noopener noreferrer"&gt;proxy-web-storage&lt;/a&gt; which has over 200 stars now. It can helps some developers manage storage more easily, so I want to share it with you. If you think this repository is useful and deserves more attention, please click a star to support it. I'll introduce it below, so let's get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  What can proxy-web-storage do?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;proxy-web-storage&lt;/code&gt; reflects every change of the storage through the &lt;code&gt;Proxy&lt;/code&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;Proxy&lt;/code&gt; object enables you to create a proxy for another object, which can intercept and redefine fundamental operations for that object.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  1. Keep the type of storage value unchanged.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;local&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;proxy-web-storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello proxy-web-storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// works&lt;/span&gt;
&lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// works&lt;/span&gt;

&lt;span class="c1"&gt;// number&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="c1"&gt;// boolean&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="c1"&gt;// null&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="c1"&gt;// object&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hello&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;proxy-web-storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// works&lt;/span&gt;

&lt;span class="c1"&gt;// array&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;proxy-web-storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// works&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="c1"&gt;// 2&lt;/span&gt;

&lt;span class="c1"&gt;// Date&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2000-01-01T00:00:00.000Z&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getTime&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;946684800000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="c1"&gt;// RegExp&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/d&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;b+&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;d/g&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cdbbdbsbz&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="c1"&gt;// function&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello proxy-web-storage!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello proxy-web-storage!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;local&lt;/code&gt; corresponds to &lt;code&gt;localStorage&lt;/code&gt;, and the same is true for &lt;code&gt;session&lt;/code&gt;. They have the same methods and properties: &lt;code&gt;key()&lt;/code&gt;, &lt;code&gt;getItem()&lt;/code&gt;, &lt;code&gt;setItem()&lt;/code&gt;, &lt;code&gt;removeItem()&lt;/code&gt;, &lt;code&gt;clear()&lt;/code&gt; and &lt;code&gt;length&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Listen to the changes.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;local&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;proxy-web-storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newVal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;oldVal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newVal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;oldVal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test.a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newVal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;oldVal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test.a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newVal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;oldVal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="c1"&gt;// test {} undefined&lt;/span&gt;

&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// test.a 1 undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It can also listens to changes triggered by other tabs.&lt;/p&gt;

&lt;h4&gt;
  
  
  on
&lt;/h4&gt;

&lt;p&gt;Subscribe to an item.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;key&lt;/code&gt;: the name of the item to subscribe to. Support &lt;code&gt;obj.a&lt;/code&gt; for &lt;code&gt;Object&lt;/code&gt; and &lt;code&gt;list[0]&lt;/code&gt; for &lt;code&gt;Array&lt;/code&gt;, and also &lt;code&gt;Array&lt;/code&gt; length.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;callback&lt;/code&gt;: the function to call when the item is changed. Includes &lt;code&gt;newValue&lt;/code&gt; and &lt;code&gt;oldValue&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  once
&lt;/h4&gt;

&lt;p&gt;Subscribe to an item only once.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;key&lt;/code&gt;: the name of the item to subscribe to. Support &lt;code&gt;obj.a&lt;/code&gt; for &lt;code&gt;Object&lt;/code&gt; and &lt;code&gt;list[0]&lt;/code&gt; for &lt;code&gt;Array&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;callback&lt;/code&gt;: the function to call when the item is changed. Includes &lt;code&gt;newValue&lt;/code&gt; and &lt;code&gt;oldValue&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  off
&lt;/h4&gt;

&lt;p&gt;Unsubscribe from an item or all items.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;key(optional)&lt;/code&gt;: the name of the item to unsubscribe from. If no key is provided, it unsubscribes you from all items.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;callback(optional)&lt;/code&gt;: the function used when binding to the item. If no callback is provided, it unsubscribes you from all functions binding to the item.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Set expires for items.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;local&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;proxy-web-storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello proxy-web-storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setExpires&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// within 10's&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="c1"&gt;// 'hello proxy-web-storage'&lt;/span&gt;

&lt;span class="c1"&gt;// after 10's&lt;/span&gt;
&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The expires is saved to localStorage. So page refresh or close will not affect its expiration. Within 10's, the value still exists. But after 10's, it has been removed.&lt;/p&gt;

&lt;h4&gt;
  
  
  setExpires
&lt;/h4&gt;

&lt;p&gt;set expires for an item.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;key&lt;/code&gt;: the name of the item to set expires.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;expires&lt;/code&gt;: accept &lt;code&gt;string&lt;/code&gt;、&lt;code&gt;number&lt;/code&gt; and &lt;code&gt;Date&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  getExpires
&lt;/h4&gt;

&lt;p&gt;return the expires(&lt;code&gt;Date&lt;/code&gt;) of the item.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;key&lt;/code&gt;: the name of the item that has set expires.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  removeExpires
&lt;/h4&gt;

&lt;p&gt;cancel the expires of the item.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;key&lt;/code&gt;: the name of the item that has set expires.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The features of &lt;a href="https://github.com/KID-joker/proxy-web-storage" rel="noopener noreferrer"&gt;proxy-web-storage&lt;/a&gt; are the above. But I would like to ask how to do the e2e test of localStorage? If you have any suggestion, whether it is about e2e testing or about the repository, please contact me or open an issue. Thanks for reading.&lt;/p&gt;

</description>
      <category>welcome</category>
      <category>community</category>
    </item>
  </channel>
</rss>
